通过此函数判断数据x是否为y类型。如:
>>> print(isinstance(10,int)) True >>> print(isinstance((10,7,3),tuple)) True >>> print(isinstance("yyf&zx",float)) False
通过此函数获得组合数据类型x的元素个数。如:
>>> print(len("string")) 6 >>> print(len((1,2,3))) 3
在C语言中,可以通过指针对于指针所指内存中储存的数据直接进行操作,也是用C实现链表、树、图的重要工具。在Python语言中并没有直接提出指针概念以进行C一样的底层操作。但可将所有Python变量理解为指针(只不过在在进行打印和赋值等操作时自动*了一把)。
指针可以理解为内存的门牌号,通过一个指定的门牌号(指针)访问一个指定的房间(一块内存)。可以将指针理解为“箭头”、“钥匙”等。如:
1、将变量a赋值为10(b赋值为5),即将a这个指针指向int10;同时将变量A赋值为[1,2,3](B赋值为[4,6,6]),这是将A这个指针指向一堆指针(A[0]、A[1]…),他们分别指向其储存的内容。
已执行代码:
>>>a = 10 >>>b = 5 >>>A = [1,2,3] >>>B = [4,6,6] >>>print(a,b,A,B) 10 5 [1,2,3] [4,6,6]
图示1:
2、将int a赋值给变量b,即将b这个指针指向a所指的地方;同时将list A赋值给B,这是将B所指的这一堆指针换成A所指的那一堆指针。
已执行代码:
>>>a = 10 >>>b = 5 >>>A = [1,2,3] >>>B = [4,6,6] >>>print(a,b,A,B) 10 5 [1,2,3] [4,6,6] >>>b = a >>>B = A >>>print(a,b,A,B) 10 10 [1,2,3] [1,2,3]
图示2:
3、那么此时继续将a赋值为20,就是将a这个指针转而指向20,此时b仍然指向原来的10,不受影响;同时将A通过赋值语句改为[7,8,9](A=[7,8,9]),这是将A指针所指的那一堆指针直接换成另一堆,这一堆指针又分别指向7,8,9,故B不受影响。
已执行代码:
>>>a = 10 >>>b = 5 >>>A = [1,2,3] >>>B = [4,6,6] >>>print(a,b,A,B) 10 5 [1,2,3] [4,6,6] >>>b = a >>>B = A >>>print(a,b,A,B) 10 10 [1,2,3] [1,2,3] >>>a = 20 >>>A = [7,8,9] >>>print(a,,b,A,B) 20 10 [7,8,9] [1,2,3]
图示3:
4、在3中,我们通过赋值语句A=[7,8,9]直接改变了A指针所指的一堆指针,B不受影响;如果不进行这样(3)的操作,转而进行改变列表元素的操作A[0]=10,这是将A指向的原来指向1的A0指针重新指向10,所以B也会受到改变。
已执行代码:
>>>a = 10 >>>b = 5 >>>A = [1,2,3] >>>B = [4,6,6] >>>print(a,b,A,B) 10 5 [1,2,3] [4,6,6] >>>b = a >>>B = A >>>print(a,b,A,B) 10 10 [1,2,3] [1,2,3] >>>A[0] = 10 >>> print(A,B) [10, 2, 3] [10, 2, 3]
图示4:
a==b返回一个真值,若为Ture代表a和b所指地址所放的内容相同;a is b同样返回一个真值,若为Ture代表a与b指向同一个地方。如:
>>> a=[1,2,1] >>> b=[1,2,1] >>> print(a is b,a==b) False True >>> c=d=[1,2,1] >>> print(c is d,c==d) True True
再如:
>>> a=10 >>> b=10 >>> print(a is b,a==b) True True >>> c="string" >>> d="string" >>> print(c is d,c==d) True True
为何同样是先用一样内容的东西给a和b赋值,用list类型(dict、set也是)打印a is b为True,而用int类型(float、complex、str、tuple也是)打印a is b为False?
这是因为,a=10;b=10;的操作将a指向一个10,将b指向一个10,而计算机中常量10只有一个,所以(a is b)=True;而进行A=[1,2,1];B=[1,2,1];的操作时,A和B分别指向一片储存着一堆指针的内存地址,这两片内存不同,只是这两片内存中的两堆地址指向的1,2,1常量相同,所以(A is B)=False(可参见上面的图示)。
所以,对于int、float、complex、str、tuple类型的变量,不必关注is和==的区别,因为这些类型本身并不可改变,不会出现改变了a的指向b也跟着变的情况,其中int、float、complex、str类型,a is b和a==b等价。而对于list、set、dict类型则要格外注意is和==的区别。
Python中的元组数据类型是由数个逗号分隔的元素(类型不限)组成,前后可加圆括号,元组不能修改(不增、不减、不改(不能对元素进行赋值操作)、不排(不能修改顺序))。
元组类型的每一个元素都可以看作指针,元组元素不可修改指的是不可以改变每个元组元素(指针)的指向,但这些元素指向的内容是可以被修改的。 如:
>>> tup=(10,"string",[1,2,3],{1:100},None) >>> tup[0]=1 Traceback (most recent call last): #我们看到对元组元素进行赋值会报错 File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment >>> tup[2][0]=10 #但可修改列表类型元素的内容 >>> print(tup) (10, 'string', [10, 2, 3], {1: 100}, None)
字符串可参考此链接
tup*n或n*tup | 将tup复制n次 |
---|---|
tup1=tup2+tup3 | 新建一个元组tup1为tup2和tup3连接后的样子 |
tup+=tup_sub | 新建一个元组仍命名为tup,为原tup和tup_sub连接后的样子 |
元组之间比大小 | 逐个元素相比,直至分出大小,若有对应元素之间不可比,则runtime error |
tuple() | 将其他数据类型转为类型 |
Python语言中,列表数据类型是由逗号分隔开的各个元素加上方括号,列表元素可以是任何类型。
a=a+b是重新对a进赋值,而a+=b是在a后方添加b的所有元素。如:
>>> a=b=[1,2,3] >>> a+=[4] >>> print(a,b) #a和b指向同一地方,改变a内容即改变b内容 [1, 2, 3, 4] [1, 2, 3, 4] >>> a=a+[5] >>> print(a,b) #对a进行重新赋值,从此与b分道扬镳 [1, 2, 3, 4, 5] [1, 2, 3, 4]
+ | 通过a+b将两个列表相连接 |
---|---|
list*n或n*list | 表示将list的所有元素复制n次 |
列表比大小 | 元素逐个相比,直至分出大小,若有两个对应元素无法比较,则runtime error |
排序问题:有N个元素的列表,想要让它所有的元素依据某一特定顺序排列。排序有很多种,插入排序、冒泡排序、快速排序、归并排序、堆排序、桶排序等。下面介绍Python封装好的排序函数,list.sort()和sorted(),其时间复杂度为O(N*logN),为稳定排序。
1、直接使用list.sort()将所有元素从小到大排序。如:
>>> list=["yyf","yt","yfz","hgj"] >>> list.sort() >>> print(list) ['hgj', 'yfz', 'yt', 'yyf']
2、直接使用LIST=sorted(list)函数得到list从小到大排序后的结果,但不改变list。如:
>>> list=[9,8,7,6,5,4,3,2,1] >>> LIST=sorted(list) >>> print(list,LIST) [9, 8, 7, 6, 5, 4, 3, 2, 1] [1, 2, 3, 4, 5, 6, 7, 8, 9]
3、通过自定义关键字函数key实现更加复杂的排序操作。list.sort(key)中的key函数为关键字函数默认为lambda x: x,该函数在排序时将列表中每一个元素作为参数,返回值作为排序的关键字,即排序的依据。如:
>>> list=[(1,2,3),(1,1,1),(10,-100,0),(1,2,2)] >>> def myKey(x): #即将每个元组的所有元素之和作为关键字 ... return sum(x) >>> list.sort(key=myKey) >>> print(list) [(10, -100, 0), (1, 1, 1), (1, 2, 2), (1, 2, 3)]
4、当然sorted()中我们也可以添加自定义的关键字函数参数来实现自定义的排序。如:
>>> list=[(1,2,3),(1,1,1),(10,-100,0),(1,2,2)] >>> def myKey(x): #这里我们将每个元组的第一个元素当作关键字 ... return x[0] >>> LIST=sorted(list,key=myKey) >>> print(list,LIST) [(1, 2, 3), (1, 1, 1), (10, -100, 0), (1, 2, 2)] [(1, 2, 3), (1, 1, 1), (1, 2, 2), (10, -100, 0)]
5、通过改变reverse参数实现从大到小排序。list.sort()和sorted()函数中reverse参数默认为False,表示从小到大排序;将其改为Ture即可从大到小排序。
>>> list=[1,2,3,0,6,4,5] >>> list.sort() >>> print(a) [1, 2, 3, 4, 5] >>> list.sort(reverse=True) >>> print(list) [6, 5, 4, 3, 2, 1, 0]
del(关键字) | 删除元素,如,del list[0] |
---|---|
list.append(x) | 将x当作一个元素加在list最尾处 |
sum(list) | 求和函数,各元素求和 |
list.count(x) | 返回列表中x的个数(作为元素的x) |
list.extend(x) | 添加列表x在列表list尾处,功能同+= |
list.insert(i,x) | 将x作为元素添加在下标为i处 |
list.remove(x) | 删除元素x,若x不在列表中,引发异常 |
list.reverse() | 将list颠倒 |
list.index(x) | 查找x,返回第一次找到的下标,找不到引发异常 |
list.index(x,s) | 从下标为s处开始实现inde(x)功能 |
list() | 将其他类型数据转为列表类型 |
map(function,sequence)函数可将一个序列映射到另一个序列,其映射规则由参数function函数决定,参数sequence为映射前序列,返回一个延时求值对象,可以通过tuple()、list()等函数将其转换成元组、列表等类型。如:
>>> def f(x): ... print("f函数执行次数++") ... return x**2 >>> a=map(f,[1,2,3,4]) #此时函数f()并未执行,a是延时求值对象 >>> print(list(a)) #将a转为list类型时,f()才开始执行,将sequence中元素依次当作参数传入,返回同样类型的变量 f函数执行次数++ #当然python并不支持++语法 f函数执行次数++ f函数执行次数++ f函数执行次数++ [1, 4, 9, 16]
列表映射可配合其他函数用于输入,如:
>>> a,b,c=map(int,input().split()) 1 2 3 #这是输入 >>> print(a,b,c) 1 2 3
filter(function,sequence)函数,作用是抽取序列中使得function(x)为True的元素x,返回一个延时求值对象。如:
#该段代码实现抽取列表l中个位数为1的元素 >>> l=[1,11,111,2,3,4,51,6,71] >>> L=list(filter(lambda x:x%10==1,l)) >>> print(L) [1, 11, 111, 51, 71]
当需要生成元素具有一定规律但又很多的列表时,既可以采用循环加append的方式,也可以采用更为简洁的列表生成式。
>>> l=[x**2 for x in range(10)] #简单生成 >>> print(l) [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] >>> l=[x*y for x in range(5) for y in range(5,10)] #双重循环 >>> print(l) [0, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 15, 18, 21, 24, 27, 20, 24, 28, 32, 36] >>> l=[x**2 for x in range(10) if x%2==0] #加上判断语句 >>> print(l) [0, 4, 16, 36, 64]
二维列表即可看作矩阵,a[i][j]即为第i行第j列的元素(行优先)。定义二维数组的方法:1、通过append(一个列表)的方式2、借助列表生成式3、直接定义。如:
>>> li=[] #1 >>> for i in range(3): ... li.append([0]*4) >>> print(li) [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] >>> li=[[0 for i in range(4)] for j in range(3)] #2 >>> print(li) [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] >>>li=[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] #3 >>>print(li) [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] #但不可通过这样的方式定义 >>> l=[0]*4 >>> li=[l]*3 >>> print(li) [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] #看起来也是一个4乘3的矩阵吗,但由于生成时从[l]*3而来,所有li中的三个元素实际上指向内容相同 #若修改li[0][0],li[1][0],li[2][0]、l[0]都会发生改变 >>> li[0][0]=100 >>> print(li,l) [[100, 0, 0, 0], [100, 0, 0, 0], [100, 0, 0, 0]] [100, 0, 0, 0]
1、似乎拷贝仅仅是a=b的事,如:
>>> a=[1,2,3] >>> b=a
但结合变量的指针实质来看,这样仅仅导致了上文图示2的效果。
>>> a[0]=100 >>> print(a,b) [100, 2, 3] [100, 2, 3]
所有这样并未拷贝任何东西,毫无意义,反而导致变量名称冗余。
2、切片拷贝
我们通过切片操作来进行列表每个元素指针的拷贝(b=a[:]),这样就新生成了一堆不同的指针指向最初列表指针指向的地方,但只拷贝了指针未拷贝指针所指内容,仍然未进行深拷贝(彻底完全拷贝)。
>>> a=[1,[2,3]] >>> b=a[:] >>> b.append(4) >>> print(a,b) #a,b看似已经分开 [1, [2, 3]] [1, [2, 3], 4] >>> b[1][0]=200 >>> print(a,b) #其实并没有,“第一层已经分开,第二层却还一样” [1, [200, 3]] [1, [200, 3], 4]
执行完后的样子:
3、利用copy库进行深拷贝。
利用copy库中的copy.deepcopy()函数可以进行真正意义上的深拷贝。既拷贝指针又拷贝指针所指内容,让a和b完全脱离。如:
>>> import copy >>> a=[1,[2,3]] >>> b=copy.deepcopy(a) >>> print(a,b) [1, [2, 3]] [1, [2, 3]] >>> a.append(4) >>> b[1][0]=200 >>> print(a,b) [1, [2, 3], 4] [1, [200, 3]]
Python语言中,字典数据类型的每个元素由键和值两部分组成,形式如:“key:value”,可以根据键对值进行快速查找(若查找的键不存在,引发异常)。如:
>>>d = {key1:value1,key2:value2} >>> d={1:"yyf",2:"fff",3:"yyy",4:"ffy"} >>> print(d[1]) yyf
字典所有元素的键必须不同(内容不同),键也必须是不可变的数据类型,如str、tuple、int、float、complex。
可以添加元素、对元素的值进行修改、删除元素,如:
>>> d={1:"yyf",2:"fff",3:"yyy"} >>>d[4]="ffy" #添加元素 >>>d[1]="YYF" #修改值 >>>print(d) {1:"YYF",2:"fff",3:"yyy",4:"ffy"} >>>del d[4] #删除元素 >>>print(d) {1:"YYF",2:"fff",3:"yyy"} >>>print(1 in d) #判断是否有元素键为1 True
字典可直接构造或使用dict()函数,如:
>>> d={1:10,2:20,3:30} #直接赋值构造 >>> print(d) {1: 10, 2: 20, 3: 30} >>> d=dict(name="BOB",age=12,height=2.22) #通过dict()构造 >>> print(d) {'name': 'BOB', 'age': 12, 'height': 2.22} >>> d=dict([(1,100),(2,200)]) >>> print(d) {1: 100, 2: 200}
get(key,v) | 若键key存在,返回其值,否则返回v |
---|---|
clear() | 清空 |
keys() | 取键的序列 |
values() | 取值的序列 |
items() | 取元素的序列 |
pop(x) | 删除键为x的元素,没有则引发异常 |
copy() | 浅拷贝 |
可以通过上述keys()、values()、items()函数生成的序列便利字典。注意,这些序列既不是list、也不是tuple、dict、set等。另外,字典元素的顺序值得注意:在python3.5及以前的版本,字典元素无顺序;在python3.6及以后的版本,字典元素的顺序与元素加入字典时的顺序相同。
字典实现深拷贝的途径与list相同,即copy.deepcopy()。
Python语言中集合数据类型的概念与数学上集合概念相同。具有如下特点:集合元素互异、集合元素无序、集合元素只能是不可变的数据类型(int、float、complex、tuple、str),其中tuple中如含有可变数据类型,也不能作为集合元素。集合的作用往往是判断一个东西是否在一堆东西里面。
集合可直接定义,也可通过set()函数将其他类型变量转为集合。如:
>>> s={1,2,3,4,2,5} #直接定义,会自动去重 >>> print(s) {1, 2, 3, 4, 5} >>> s=set([1,2,3,4,5,6,4,8]) #通过set()定义 >>> print(s) {1, 2, 3, 4, 5, 6, 8} >>> s=set({1:10,2:20}) #字典类型只取其键 >>> print(s) {1, 2} >>> s=set("string") >>> print(s) {'t', 'i', 's', 'r', 'n', 'g'}
clear() | 清空 |
---|---|
add(x) | 将x作为元素添加进集合 |
update(x) | 将序列x中所有元素加入集合 |
copy() | 浅拷贝 |
remove(x) | 删除元素x,若没有则引发异常 |
与数学上集合概念相同,Python中集合数据类型也可进行交并等运算。如:
a,b是集合
x in a | 返回真值,x是否在a中 |
---|---|
a|b | 并 |
a&b | 交 |
a-b | 差,在a中而不在b中的元素组成的集合 |
a^b | a与b的对称差,即(a|b)-(a&b) |
a==b | a、b是否一样 |
a!=b | a、b是否不一样 |
a<=b(b>=a) | a是否是b的子集 |
a<b(b>a) | a是否是b的真子集 |