0%

一些基础语法

1、条件控制

一般形式:

1
2
3
4
5
6
if condition_1:
statement_block_1
elif condition_2:
statement_block_2
else:
statement_block_3
  • 记得在条件后加:
  • Python 中用 elif 代替了 else if,所以if语句的关键字为:if – elif – else
  • python中没有switch语句,python3.10后更新了类似语法,由于我是3.9,就不写在这里了

2、循环语句

while语句

可以与else配合使用:

1
2
3
4
while <expr>: #记得冒号
<statement(s)>
else:
<additional_statement(s)>

while中的break和continue用法同C

for语句

一般格式

1
2
3
4
5
6
7
8
9
10
11
12
13
a = 'dhk'
for x in a:
print(x,end='') #dhk
else: #else用于在循环结束后执行的内容
print("error!!")

sites = ["Baidu", "Google","Runoob","Taobao"]
for site in sites:
print(site)

questions = {'name': 'lancelot', 'quest':'the holy grail', 'favorite color':'blue'}
for q,b in questions.items(): #字典会稍微复杂一点
print(f'{q} {b}')

不同于C,python的for语句常用来遍历某个可迭代对象,如列表、字符串,如上的循环中,x每次只取遍历对象的最基本单位并自动递增

range函数

生成一个数字序列,格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
for x in range(1,10,2):
print(x,end='')#13579


>>>a = ['Google', 'Baidu', 'Runoob', 'Taobao', 'QQ']
>>> for i in range(len(a)):
... print(i, a[i])
...
0 Google
1 Baidu
2 Runoob
3 Taobao
4 QQ
>>>

range函数的指定区间同样遵循左闭右开的原则

pass语句

空语句,表示空

3、迭代器

迭代是Python最强大的功能之一,是访问集合元素的一种方式

大概作用和C的指针有点像?

迭代器是一个可以记住遍历的位置的对象。

迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    list = [1, 2, 3, 4]
it = iter(list) # 创建迭代器对象
it2 = iter(list) # 创建迭代器对象
for x in it:
if x != 4:
print(x, end=" ")
else:
print(x)
print(next(it2))
print(next(it2))
print(next(it2))
print(next(it2))
'''
1 2 3 4
1
2
3
4
'''

把一个类作为迭代器使用:

若想把一个类作为迭代器使用,需要在类中实现两个方法:

  • __iter__():返回一个特殊的迭代器对象, 这个迭代器对象实现了 next() 方法并通过 StopIteration 异常标识迭代的完成。

  • __next__():返回下一个迭代器对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
       class MyNumbers:
    def __iter__(self):
    self.a = 1
    return self

    def __next__(self):
    if self.a <= 20:
    x = self.a
    self.a += 1
    return x
    else:
    raise StopIteration #挂起StopIteration标志迭代完成,不能用return
    a = MyNumbers()
    i = iter(a)
    for x in i:
    print(x, end=' ')
    #1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

4、生成器

在 Python 中,使用了 yield 的函数被称为生成器(generator)。

在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。

  • 生成器函数返回的是一个迭代器对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import sys

def fibonacci(n): # 生成器函数 - 斐波那契
a, b, counter = 0, 1, 0
while True:
if (counter > n):
return
yield a
a, b = b, a + b
counter += 1
f = fibonacci(10) # f 是一个迭代器,由生成器返回生成

while True:
try:
print (next(f), end=" ")
except StopIteration:
sys.exit()

5、函数

规则:

  • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()
  • 函数内容以冒号 : 起始,并且缩进。(记得冒号!!)
  • 与C不同,py的函数不需要确定返回值类型,直接return就可以
1
2
def 函数名(参数列表):
函数体

关键字参数

在调用函数时,实参可以是key=value的形式,称为关键字参数。

凡是按照这种形式定义的实参,可以不按照从左到右的顺序定义,但仍能为指定的形参赋值。

  • 关键字参数在位置参数后面,因为python函数在解析参数时,是按照顺序来的,位置参数是必须先满足,才考虑其他可变参数。

    1
    2
    3
    4
    5
    6
    def printinfo(age, name):
    print("名字: ", name)
    print("年龄: ", age)
    return

    printinfo(50, name="runoob") #age为位置参数,name为关键字参数

    需要注意:

    • 位置参数的输入必须和定义时的位置相同
    • 关键字参数的输入必须在位置参数之后

当参数不定长时

1
def printinfo( arg1, *vartuple ):

加了星号 * 的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数

当参数添加双星号**时,传入的参数将以字典的形式保存

1
2
3
4
5
def func(**dic)
print(dic)
func(**{'a':1,'b':2})
#or
func(a=1,b=2)

匿名函数

Python 使用 lambda 来创建匿名函数

  • lambda 的主体是一个表达式,而不是一个代码块。仅仅能在 lambda 表达式中封装有限的逻辑进去。
1
2
3
4
5
6
7
8
9
10
# 可写函数说明
sum = lambda arg1, arg2: arg1 + arg2

# 调用sum函数
print ("相加后的值为 : ", sum( 10, 20 ))
print ("相加后的值为 : ", sum( 20, 20 ))
'''
30
40
'''

强制位置参数&命名关键字参数

1
2
3
# a, b, c成为限定位置形参
def func(a, b, c, /, d):
pass
1
2
3
#这时参数kw1, kw2必须传入关键字参数
def func(其他形参, *, kw1, kw2):
pass

6、类

Python中的类提供了面向对象编程的所有基本功能:类的继承机制允许多个基类,派生类可以覆盖基类中的任何方法,方法中可以调用基类中的同名方法。

定义:

1
2
3
4
5
class MyClass:
i = 12345
a = 1
def f(self):#类中的函数称作类的方法
return 'hello world'

类的初始化(构造方法),这里注意类的方法的第一个参数

1
2
3
4
5
6
class Complex:
name = ''
age = 0
def __init__(self, n, a): #类的方法必须包含self,且其必须为第一个参数
self.name = n
self.age = a

创建一个类的实例:

1
x = MyClass()

访问类的属性、方法:

1
2
print("MyClass 类的属性 i 为:", x.i)
print("MyClass 类的方法 f 输出为:", x.f())

类的继承:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#类定义
class people:
#定义基本属性
name = ''
age = 0
#定义私有属性,私有属性在类外部无法直接进行访问
__weight = 0
#定义构造方法
def __init__(self,n,a,w):
self.name = n
self.age = a
self.__weight = w
def speak(self):
print("%s 说: 我 %d 岁。" %(self.name,self.age))

#单继承示例
class student(people):
grade = ''
def __init__(self,n,a,w,g):
#调用父类的构函
people.__init__(self,n,a,w)
self.grade = g
#重写父类的方法
def speak(self):
print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))



s = student('ken',10,60,3)
s.speak()
  • 子类中若出现了父类同名的方法,则在调用该子类方法时使用的内容也是子类中定义的内容

私有属性与方法:

方法或属性的开头加两个下划线,声明(不包含在变量名中)该属性为私有,不能在类的外部被使用或直接访问

文件间的引用

1、import语句

想使用一个 Python 源文件,只需在另一个源文件里执行 import 语句导入该模块(就是后缀为.py的文件)

  • 一个模块只会被导入一次,不管你执行了多少次 import。这样可以防止导入模块被一遍又一遍地执行。

2、from..import语句

从模块中导入指定的部分,例如:

1
2
3
from test_file import test_fuction1,test_fuction2
#从test_file.py中导入两个函数
#将某个模块中的全部函数导入,格式为from somemodule import *

3、使用模块中的变量、函数

通过modname.itemname 这样的表示法来访问模块内的函数

4、_name__属性

一个模块被另一个程序第一次引入时,其主程序将运行。每个模块都有一个name属性,当其值是’main‘时,表明该模块自身在运行,否则是被引入。

1
2
3
4
if __name__ == '__main__':
print('程序自身在运行')
else:
print('其他程序在运行')

可以通过name属性使某个文件仅在自身运行而非被引用时运行某些函数

5、包

包是一种管理 Python 模块命名空间的形式,采用”点模块名称”。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
sound/                          顶层包
__init__.py 初始化 sound 包
formats/ 文件格式转换子包
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
effects/ 声音效果子包
__init__.py
echo.py
surround.py
reverse.py
...
filters/ filters 子包
__init__.py
equalizer.py
vocoder.py
karaoke.py
...

目录只有包含一个叫做 _ _init__.py 的文件才会被认作是一个包

  • 导入方法

    导入模块

    1
    from sound.effects import echo

    导入函数、变量

    1
    from sound.effects.echo import echofilter
  • 导入多个子模块

    在sound/下的init文件中:

    1
    __all__ = ["echo", "surround", "reverse"]

    由于windows不区分大小写,因此可以通过这种方式在当使用导入*时区分大小写地导入子模块

读、写文件

1
f=open(name,mode)

mode可选:

模式 描述
r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
rb 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。
r+ 打开一个文件用于读写。文件指针将会放在文件的开头。
rb+ 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
w 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
wb 以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
w+ 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
wb+ 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
a 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
ab 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
ab+ 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。

open的其他方法见:Python3 File 方法 | 菜鸟教程 (runoob.com)

文件对象的其他方法见Python3 输入和输出 | 菜鸟教程 (runoob.com)

局部变量和全局变量

在局部作用域修改全局变量,感觉。。还是我们C方便。。。

1
2
3
4
5
6
7
8
num = 1
def fun1():
global num # 需要使用 global 关键字声明
print(num)
num = 123
print(num)
fun1()
print(num)

Numpy库

array操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
a = np.zeros((1, 5))                                       
print(f"a shape = {a.shape}, a = {a}")

a = np.zeros((2, 1))
print(f"a shape = {a.shape}, a = {a}")

a = np.random.random_sample((1, 1))
print(f"a shape = {a.shape}, a = {a}")

'''
a shape = (1, 5), a = [[0. 0. 0. 0. 0.]]
a shape = (2, 1), a = [[0.]
[0.]] #此处为2个行向量
a shape = (1, 1), a = [[0.78320514]]
'''


a = np.array([[5], [4], [3]])
print(f" a shape = {a.shape}, np.array: a = {a}")

'''
a shape = (3, 1), np.array: a = [[5]
[4]
[3]]
'''

索引

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
a = np.arange(6).reshape(-1, 2)   #将0~5转化为?行,2列的格式
print(f"a.shape: {a.shape}, \na= {a}")
'''
a.shape: (3, 2),
a= [[0 1]
[2 3]
[4 5]]
'''

#索引某个元素(索引从0开始,因此索引的为第3排第1列)
print(f"\na[2,0].shape: {a[2, 0].shape}, a[2,0] = {a[2, 0]}, type(a[2,0]) = {type(a[2, 0])} Accessing an element returns a scalar\n")
'''
a[2,0].shape: (), a[2,0] = 4, type(a[2,0]) = <class 'numpy.int32'> Accessing an element returns a scalar
'''

#索引某一行
print(f"a[2].shape: {a[2].shape}, a[2] = {a[2]}, type(a[2]) = {type(a[2])}")
'''
a[2].shape: (2,), a[2] = [4 5], type(a[2]) = <class 'numpy.ndarray'>
'''

np.expand_dims

我也还不太清楚具体用法,先做个记录,可以仿照着用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
A = np.arange(1,11).reshape(1,-1) #只有1行的二维
print(f'{A}\n')
A = np.expand_dims(A,axis=2)
print(f'{A}\n{A.shape}')
A = A[:,:,0]
print(f'{A}\n')

'''
[[ 1 2 3 4 5 6 7 8 9 10]]

[[[ 1]
[ 2]
[ 3]
[ 4]
[ 5]
[ 6]
[ 7]
[ 8]
[ 9]
[10]]]
(1, 10, 1)
[[ 1 2 3 4 5 6 7 8 9 10]]
'''

np.pad

对数组在不同维度填充值,默认为0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import numpy as np

A = np.arange(1,11).reshape(2,-1)
A = np.expand_dims(A,axis=2) #变为3维
A = np.pad(A,((1,2),(0,0),(0,0)))
print(f'{A}\n')

'''
[[[ 0]
[ 0]
[ 0]
[ 0]
[ 0]]

[[ 1]
[ 2]
[ 3]
[ 4]
[ 5]]

[[ 6]
[ 7]
[ 8]
[ 9]
[10]]

[[ 0]
[ 0]
[ 0]
[ 0]
[ 0]]

[[ 0]
[ 0]
[ 0]
[ 0]
[ 0]]]

'''
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
A = np.pad(A,((0,0),(1,2),(0,0)))
print(f'{A}\n')

'''
[[[ 0]
[ 1]
[ 2]
[ 3]
[ 4]
[ 5]
[ 0]
[ 0]]

[[ 0]
[ 6]
[ 7]
[ 8]
[ 9]
[10]
[ 0]
[ 0]]]

'''
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
A = np.pad(A,((0,0),(0,0),(1,2)))
print(f'{A}\n')

'''
[[[ 0 1 0 0]
[ 0 2 0 0]
[ 0 3 0 0]
[ 0 4 0 0]
[ 0 5 0 0]]

[[ 0 6 0 0]
[ 0 7 0 0]
[ 0 8 0 0]
[ 0 9 0 0]
[ 0 10 0 0]]]
'''

matplotlib.pyplot库

用法接近matlab

subplots

1
2
3
4
5
fig, axarr = plt.subplots(6)
axarr[0].plot(...)
axarr[1].imshow()
...
plt.show()

subplot

1
2
3
4
5
plt.subplot(1,2,1)
plt.plot(...)
plt.subplot(1,2,2)
plt.plot(...)
plt.show()

OS库

os.listdir()

os.listdir() 方法用于返回指定的文件夹包含的文件或文件夹名字列表

os.path()

Python os.path 模块 | 菜鸟教程 (runoob.com)

os.path.join(path1[, path2[, …]])

把path1path2合成一个路径

字符串、向量和数组

1、using声明

作用:使用using声明命名空间的相关成员后,后续不需再声明

1
2
3
using std::cin;
int i;
cin>>i;
  • 每个名字都需要独立的using声明

2、string类型

  • 使用前需包含头文件<string>(没有.h),且需声明string定义于命名空间中

初始化string类型的方法

1
2
3
4
5
string s1;
string s2=s1;
string s3("value");
string s3 ="value";
string s4(n,'c');//此处只能为字符

读写string对象

当要将标准输入内容读取到一个string对象时,string对象会自动忽略开头的空白(空格、换行等),从第一个真正的字符开始,直到遇到遇到下一个空白(但读取结束的标准是换行)

使用getline函数读取一整行

1
2
string s;
getline(cin,s);

getline只有当读取到换行符时才会结束,并且这个换行符会被丢弃。

相加问题

string对象可以相加,string对象也可以与字面值相加,但字面值不能与字面值相加!

单独处理字符

C++11提供了一种语句:范围for

1
2
string str("something");
for(auto c:str) cout<<c<<endl;
  • 每次循环中,都会把序列中的基础元素存入c中

还可以通过引用等方式单独改变字符

1
2
string str("something");
for(auto &c:str) c=toupper(c);//大写转换函数

下标问题

C++支持对字符串使用下标运算符[]访问字符串的单个字符,规则同python,但貌似C++不支持截取。

3、vector类型

要想使用vector,需包含<vector>头文件。类型vector表示对象的集合

实例化:

1
2
vector<int> a;
vector<vector<int>> b;

定义与初始化

1
2
3
4
5
6
7
vector<int> a;
vector<int> a(b); //a包含b中所有元素的副本 a和b的类型需相同
vector<int> a=b;
vector<int> a(n,val); //a中有n个重复的val
vector<int> a(n); //包含n个对象
vector<int> a{A,B,C};
vector<int> a={A,B,C};

向vector对象尾部添加元素

1
2
vector<int> a;
a.push_back(1);//a={1}

其他函数

1
2
a.empty(); //如果a不含元素则返回真
a.size(); //返回元素个数

其他的类函数参考书p91

索引

vector对象同样支持使用下标运算符进行单个元素的索引,但不能通过下标添加元素。

4、迭代器

迭代器(iterator)是一种可以遍历容器元素的数据类型。迭代器是一个变量,相当于容器和操纵容器的算法之间的中介。C++更趋向于使用迭代器而不是数组下标操作,因为标准库为每一种标准容器(如vector、map和list等)定义了一种迭代器类型,而只有少数容器(如vector)支持数组下标操作访问容器元素。可以通过迭代器指向你想访问容器的元素地址,通过*x打印出元素值。这和我们所熟知的指针极其类似。

C语言有指针,指针用起来十分灵活高效。
C++语言有迭代器,迭代器相对于指针而言功能更为丰富。

迭代器的使用

可以看出,迭代器的基本使用和指针极其相似

1
2
3
4
5
6
7
8
int main()
{
vector<string> v{"aaaa","bbbb"};
auto i=v.begin();
cout<<*(i+1); //bbbb
system("pause");
return 0;
}

迭代器运算符

  • 获得迭代器所指元素

    1
    *iter  or  iter->mem
  • 获取迭代器长度

    1
    i.end()-i.begin()

迭代器类型

1
2
3
4
5
6
7
8
9
10
11
vector<string> v{"aaaa","bbbb"};
auto i=v.begin();
//vector<string>::iterator i; 类型

string str("12345");
auto i=str.begin();
//string::iterator i; 类型

对应的只读类型
//vector<string>::const_iterator v;
//string::const_iterator str;

当需要对迭代器进行遍历时,需注意for循环的条件3:

1
2
3
4
5
6
7
8
9
10
11
int main()
{
vector<int> v{1,2,3,4,5,6,7,8,9,10};
for(auto i=v.begin(); i !=v.end(); ++i)//应使用++i,这是因为end为元素10之后的位置
{
*i=*i*2;
}
for(auto a:v) cout<<a<<endl;
system("pause");
return 0;
}

5、数组

大部分规定与C相同。

  • 定义数组时不允许用auto关键字由初始值推断类型。

  • 可使用decltype(数组名)定义数组类型。

  • 数组不是类类型,因此没有成员函数。

    因此C++11引入了begin、end函数来查询数组相关元素的地址

    1
    2
    int a[]={1,2,3};
    int *p=begin(a);

注意:end()和vector类型的子函数.end()不同,end()函数返回的是数组最后一个元素的地址,而vector类型的end子函数返回的是最后一个元素的后一位地址

单个元素类型

通常对数组的单个类型定义为size_t型,该类型为一种机器相关的无符号类型,它被设计得足够大以便能表示内存中任意对象的大小

要使用该类型,应包含cstddef头文件

C与C++的字符串风格

1
2
char a[10]="dhk"; //C风格
string a("dhk"); //C++风格

在C中,通常我们要对字符串进行一些例如比较、拷贝、连接等的操作时,通常使用的是标准库中的相关字符串长度,相较于C++中string类型的变量可以对存放字符串的变量直接进行运算等操作,C的字符串风格更加繁琐,且极容易在数组的内存方面引发严重问题

混用规则:

1
2
3
string a("dhk");
char *str=a;//错误,a的类型为string,而str类型为char*,冲突
char *str=a.c_str();//正确。c_str()函数返回的是C风格字符串(一个地址)

上述用法相当于是在内存中创建了一个”dhk”字符串,而用于找到该字符串的指针一旦改变,该字符串就将不能再被找到,因此通常对存放该类型的指针进行const操作。其规则类似C中的char *str="dhk"所遵循的规则。

使用数组初始化vector类型

C++不允许用一个数组为另一个数组赋初值,也不允许通过vector类型对象为一个数组初始化,但是允许通过数组为vector对象初始化。

1
2
int a[]={1,2,3,4,5};
vector<int> v(begin(a),end(a));

6、多维数组

一些基础内容同C,详见二维数组复习 | 小董的BLOG (gitee.io)

多维数组可以理解为数组的数组例如int a[3][4]可以理解为a数组包含三个元素,而这三个元素都为大小为4的数组

下标引用

使用范围for语句和下标引用处理多维数组

1
2
3
4
5
6
7
8
9
10
int a[3][4]={0};
size_t x=0;
for(auto &row : a)
{
for(auto &col : row)
{
col=x;
x++;
}
}

1、基本数据类型

  • 变量不需要声明,也没有类型。
  • python允许同时给多个变量赋值

标准数据类型:

  • Number
  • String
  • List
  • Tuple(元组)
  • Set(集合)
  • Dictionary(字典)

1、Number(数字)

Python3 支持 int、float、bool、complex(复数)

  • 可使用type(变量 )函数查询变量类型
  • 可用isinstance(变量,类型 )判断变量是否为想要的类型,为真返回Ture

  • del 语句可用删除对对象的引用

  • 在除法的计算中,/返回浮点数,//返回整数,在混合计算时会把整数转化为浮点数

  • //返回的不一定是整型的数,这与分母分子的类型有关

python可以使用**来进行幂运算,如5的平方:5**2

  • number为不可变类型,例如变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变 a 的值,相当于新生成了 a

  • 数字类型转换

    1
    2
    3
    4
    5
    6
    a=1.0
    int(a)
    float(a)
    complex(a) #转换为复数,实数部分为a,虚数部分为0
    b=2
    complex(a,b) #转换为复数,实数部分为a,虚数部分为b
  • 其他常用数字函数

    Python3 数字(Number) | 菜鸟教程 (runoob.com)

2、String(字符串)

Python 没有单独的字符类型,一个字符就是长度为 1 的字符串

python中的字符串可用单引号或双引号括起来,使用完全相同

字符串的截取:

1
2
3
4
5
6
7
#变量[头下标:尾下标:截取步长]
#若截取步长为负数则逆向读取
#第一个字符索引值为0,末尾字符为-1

print("dhk"*2)
print("dhk"+"dhk")
#dhkdhk
  • 字符索引:变量[索引下标]
  • 屏蔽转义字符:在字符串前(引号外)添加一个r
  • python字符串不能被改变,也就是说不能给单个索引位置赋值

字符串的格式化:print("%s %d" % ('abc', 10))

input

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
input([prompt]) #prompt为用户写的提示信息


>>>a = input("input:")
input:123 # 输入整数
>>> type(a)
<type 'int'> # 整型


>>> a = input("input:")
input:"runoob" # 正确,字符串表达式
>>> type(a)
<type 'str'> # 字符串,python3 里 input() 默认接收到的是 str 类型


>>> a = input("input:")
input:runoob # 报错,不是表达式

f-string字符串格式化

格式化字符串以 f 开头,后面跟着字符串,字符串中的表达式用大括号 {} 包起来,它会将变量或表达式计算后的值替换进去,括号中的变量不仅限于字符串

1
2
3
name = 'dhk'
print(f'hello {name}')
#hello dhk
  • print中的转义字符用法同C

print

python的输出不同于c,直接把想输出的内容通过逗号连接即可

1
2
3
a=11
b='dhk'
print(a,b)

也可以通过类似C的语法:

但是感觉这种方法不如f-string和上述用法方便简单

1
print ("我叫 %s 今年 %d 岁!" % ('小明', 10))

格式化符号详见Python3 字符串 | 菜鸟教程 (runoob.com)

  • end关键字,用于将结果输出到同一行

    1
    print(b, end=',')

转义字符

Python3 字符串 | 菜鸟教程 (runoob.com)

其中进制的转换为:

  • bin(a):转二进制
  • oct(a):转八进制
  • hex(a):转十六进制

字符串相关函数

Python3 字符串 | 菜鸟教程 (runoob.com)

3、List(列表),中括号

定义方式:

1
a=[1,10.1,'abcd']
  • 基本使用同字符串,也可以索引、截取,使用步长截取(包括逆向)等。
  • 列表内的元素可改变!,直接像c的数组一样改就行
  • 逆向读取不会将元素内容逆向

更新列表:

1
2
3
list1 = ['Google', 'Runoob', 'Taobao']
list1.append('Baidu')
print ("更新后的列表 : ", list1) #更新后的列表 : ['Google', 'Runoob', 'Taobao', 'Baidu']

删除列表元素

1
2
list1 = ['Google', 'Runoob', 'Taobao']
del list[2]

索引

变量[头下标:尾下标] or 变量[头下标:尾下标:步长]步长为-1时逆向读取

其中-1代表末尾(用于不知道实际长度时的索引),同时-2、-3对应倒数第二、第三…

正数和负数的使用不相互冲突

列表操作函数

Python3 列表 | 菜鸟教程 (runoob.com)

创建指定长度空列表

1
2
n = 5
empty_list = [None] * n

4、Tuple(元组),小括号

定义方式:

1
a=(1,10.1,'abcd')
  • 基本使用同字符串,也可以索引、截取,使用步长截取(包括逆向)等。

  • 元组在输入时可能没有括号,例如t = 12345, 54321, 'hello!'

  • 元组内元素不可改变,但可以包含可变的对象,比如列表,同时也可以对元组之间进行连接组合成新元组:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    tup1 = (12, 34.56)
    tup2 = ('abc', 'xyz')

    # 以下修改元组元素操作是非法的。
    # tup1[0] = 100

    # 创建一个新的元组
    tup3 = tup1 + tup2
    print (tup3)
  • 包含0和1个的元组有额外的语法规则:

    1
    2
    tup1 = ()    # 空元组
    tup2 = (20,) # 一个元素,需要在元素后添加逗号,否则括号会被当作运算符使用
  • 元组中只包含一个元素时,需要在元素后面添加逗号 ,否则括号会被当作运算符使用

  • 内置函数

    Python3 元组 | 菜鸟教程 (runoob.com)

5、Set(集合),大括号

定义方式:

1
2
3
4
5
6
7
8
a=() #空集合需用小括号
b={1, 2, 3}
c=set('abcde') #使用set函数={'a','b','c','d','e'}
#必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。
b.add(4)
b.update(4) #添加元素上述两种都可以
b.remove(4)
b.discard(4) #remove不存在元素会报错,discard则不会

特点:

  • 输出时会自动去掉重复的元素(从第二次重复的元素开始删除)

  • 可以进行集合运算

  • 不可像前面几个类型一样进行索引,集合是无序的

    1
    2
    3
    4
    print(a-b) #将a中与b相同的元素去掉后输出a
    print(a|b) # 并集
    print(a&b) #交集
    print(a^b) #非交集

其余内置函数

Python3 集合 | 菜鸟教程 (runoob.com)

6、Dictionary(字典)

字典是一种映射类型,它是一个无序键(key) : 值(value) 的集合。

定义方式:

1
2
3
4
5
6
7
8
9
10
a = {'a' : 1, 'b': 2, 'c' :3}  #':'前为“键”,后为“值”
#or
a= {}
a['a'] = 1
a['b'] = 2

print(a) #{'a': 'abcd', 'b': '123'}
print(a.keys()) #dict_keys(['a', 'b'])
print(a.values()) #dict_values(['abcd', '123'])
print(a['b']) #2 访问字典里的值

键的特性:

  • 同一个键出现两次时只有后一个值会被记住

  • 必须是不可变的,因此可以是数字、字符串、元组,而不能是列表等可以改变的变量

  • 修改字典

    1
    2
    3
    4
    5
    6
    7
    8
    tinydict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'}

    tinydict['Age'] = 8 # 更新 Age
    tinydict['School'] = "菜鸟教程" # 添加信息


    print ("tinydict['Age']: ", tinydict['Age'])
    print ("tinydict['School']: ", tinydict['School'])
  • 同时遍历多个序列和用单个字典表示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
questions = {'name': 'lancelot', 'quest':'the holy grail', 'favorite color':'blue'}
for q, a in questions.items():#q和a会分别遍历键和值
print(f'What is your {q}? It is {a}.')

####################or#####################

questions = ['name', 'quest', 'favorite color']
answers = ['lancelot', 'the holy grail', 'blue']
for q, a in zip(questions, answers): #索引多个序列
print(f'What is your {q}? It is {a}.')

'''
What is your name? It is lancelot.
What is your quest? It is the holy grail.
What is your favorite color? It is blue.
'''

综上

  • list元素可改变,有序
  • tuple元素不可改变,有序
  • set无序,不可索引
1
2
3
4
a=[1,10.1,'abcd']  #列表
a=(1,10.1,'abcd') #元组
a={1, 2, 3} #集合
a = {'a' : 1, 'b': 2, 'c' :3} #字典

2、推导式

Python 推导式是一种独特的数据处理方式,可以从一个数据序列构建另一个新的数据序列的结构体

Python 支持各种数据结构的推导式:

  • 列表(list)推导式
  • 字典(dict)推导式
  • 集合(set)推导式
  • 元组(tuple)推导式

列表推导式

格式:

1
[表达式 for 变量 in 列表 if 条件]
  • 表达式:需要对输出元素的操作,可以是有返回值的函数,其格式即推导式最终输出的格式
  • 变量&列表:我的理解是定义一个新变量,通过这个新变量将现有列表元素传入表达式

  • 条件:对变量进行筛选

例:

1
2
3
4
5
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
b = [i/2 for i in a if i % 2 == 0]
#定义变量i,i来自列表a中的可以整除2的元素,最后返回i/2的值作为新列表b的元素
print(b)
#[1.0, 2.0, 3.0, 4.0, 5.0]

同时定义多个变量存放值:

1
2
3
4
5
vec1 = [2, 4, 6]
vec2 = [4, 3, -9]
[x*y for x in vec1 for y in vec2]
[x+y for x in vec1 for y in vec2]
[vec1[i]*vec2[i] for i in range(len(vec1))]

在矩阵列表中使用:

1
2
3
a = [[1, 2, 3], [4, 5, 6]]
b = [row[0] for row in a]
print(b)

字典推导式

格式与列表推导式几乎相同,只是将表达式换成了key:value的格式,具体见下:

1
2
3
a = [97, 98, 99, 100, 101] # 传入推导式的为一个列表
b = {k: chr(k) for k in a}
print(b) #{97: 'a', 98: 'b', 99: 'c', 100: 'd', 101: 'e'}
1
2
3
4
5
6
7
8
9
a = {97: 'a', 98: 'b', 99: 'c', 100: 'd', 101: 'e'}# 传入推导式的为一个字典
b = {k: chr(k) for k in a.keys()}
print(b) #{97: 'a', 98: 'b', 99: 'c', 100: 'd', 101: 'e'}

#or

a = {97: 'a', 98: 'b', 99: 'c', 100: 'd', 101: 'e'}
b = {k: i for k,i in a.items()}
print(b)

但如果如下操作:

1
2
3
4
a = {97: 'a', 98: 'b', 99: 'c', 100: 'd', 101: 'e'}
b = {k: i for i in a.values() for k in a.keys()}
print(b)
#{97: 'e', 98: 'e', 99: 'e', 100: 'e', 101: 'e'}

目前还不知道原因。

集合推导式

规则格式与列表推导式相同

例:

1
2
3
a = {x for x in 'abracadabra' if x not in 'abc'} #判断不是abc的字母
print(a) #{'d', 'r'}
print(type(a)) #<class 'set'>

元组推导式(生成器表达式)

元组推导式和列表推导式的用法也完全相同,但元组推导式返回的结果是一个生成器对象

1
2
3
4
5
6
>>> a = (x for x in range(1,10))
>>> a
<generator object <genexpr> at 0x7faf6ee20a50> # 返回的是生成器对象

>>> tuple(a) # 使用 tuple() 函数,可以直接将生成器对象转换成元组
(1, 2, 3, 4, 5, 6, 7, 8, 9)

3、运算符

赋值运算符

  • := 海象运算符,在表达式内部为变量赋值:

    1
    if (n := len(a)) > 10  #可以避免调用两次len函数

python逻辑运算符

运算符 表达式 作用
and x and y x为则返回x,x为则返回y
or a or y x为则返回x,x为则返回y
not not x x为真返回假,为假返回真

python成员运算符

可用于字符串、列表、元组、集合、字典(貌似是判断键)

运算符 表达式
in x in list
not in x not in list

python身份运算符

运算符 表达式
is a is b
is not a is not b

4、其他

  • end关键字,用于将结果输出到同一行,同时将end=的内容添加在每次输出的末尾

    1
    2
    3
    4
    b=1
    while b<10
    print(b,end=',')
    b+=1
  • 多行语句

    1
    2
    3
    4
    total = item_one + \
    item_two + \
    item_three
    #在 [], {}, 或 () 中的多行语句,不需要使用反斜杠