列表
创建:
a_list = ['a','b','mpilgrim','z','example']
a_list = [] #创建空列表
- list()可以将元组,range对象,字符串,字典,集合或其他类型的可迭代对象类型的数据转换为列表
- 字典的元素转换位列表,需要使用字典对象的items()说明
>>>a_list = list((3,5,7,9,11)) #将元组转换为列表
>>>a_list
[3,5,7,9,11]
>>>list(range(1,10,2)) #将range对象转换位列表
[1,3,5,7,9]
>>>list('hello world')
['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
>>>list({3,7,5}) #将集合转换为列表
[3,7,5]
>>>list({'a':3,'b':9,'c':78}) #将字典中的key转换为列表
['a','b','c']
>>>list({'a':3,'b':9,'c':78}.items())
[('a', 3), ('b', 9), ('c', 78)]
*其他:random.shuffle() 打乱列表的顺序
>>>x = [1,2,3]
>>>del x[1] #del删除列表中的元素
>>>x
[1,3]
>>> del x #删除列表对象
>>> x #删除后无法访问,抛出异常
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>> x = {'a':1,'b':2,'c':3} #删除字典中的部分元素
>>> del x['a']
>>> x
{'b': 2, 'c': 3}
>>> x = (1,2,3) #元组不能删除
>>> del x[0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object doesn‘t support item deletion
>>> x[0] = 4 #不能修改元组中的值
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
列表的常用方法
方法 | 说明 |
---|---|
lst.append(x) | 将x添加到列表lst的尾部 |
lst.extend(L) | 将列表L中所有元素添加至lst尾部 |
lst.insert(index,x) | 在列表lst指定位置index处添加元素x,后面元素后移一位 |
lst.remove(x) | 在列表lst中删除首次出现的x元素 |
lst.pop([index]) | 删除并返回列表lst中下标为index(默认为-1)的元素 |
lst.clear() | 删除列表中所有元素,但保留列表对象 |
lst.index(x) | 返回列表中第一个值为x的元素,没有则抛出异常 |
lst.count(x) | 返回指定元素x在列表中的出现次数 |
lst.reverse() | 对列表所有元素进行逆序 |
lst.sort(key=None,reverse=Flase) | 对列表中元素进行排序,key为排序依据,Ture降序,Flase升序 |
lst.copy() | 返回列表的浅复制 |
append(),insert(),extend()
>>> x = [1,2,3]
>>> id(x)
1947928704072
>>> x.append(4) #在末尾添加元素
>>> x
[1, 2, 3, 4]
>>> x.insert(0,0) #在指定位置追加元素
>>> x
[0, 1, 2, 3, 4]
>>> x.extend([5,6,7]) #在尾部追加多个元素
>>> x
[0, 1, 2, 3, 4, 5, 6, 7]
>>> id(x)
1947928704072
- 运算符+和*也能实现增加元素,但不属于原地操作
>>> x = [1,2,3]
>>> x + [4]
[1, 2, 3, 4]
>>> x = [1,2,3]
>>> x * 2
[1, 2, 3, 1, 2, 3]
pop(),remove(),clear()
>>> x = [1,2,3,4,5,6,7]
>>> x.pop() #弹出并返回尾部元素
7
>>> x.pop(0) #弹出并返回指定位置的元素
1
>>> x.clear() #删除所有元素
>>> x
[]
>>> x = [1,2,1,1,2]
>>> x.remove(2) #删除首个值为2的元素
>>> x
[1, 1, 1, 2]
>>> del x[3] #删除指定位置的元素
>>> x
[1, 1, 1]
count(),index()
>>> x = [1,2,2,3,3,3,4,4,4,4]
>>> x.count(3) #计算3出现的次数
3
>>> x.count(5)
0
>>> x.index(2) #元素2在列表中首次出现的索引
1
>>> x.index(4)
6
>>> x.index(5) #列表中没有5,抛出异常
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: 5 is not in list
>>> 5 in x #5不是列表的元素
False
>>> 4 in x #4是列表中的元素
True
sort(),rexerve()
>>> x = list(range(11))
>>> import random
>>> random.shuffle(x) #随机乱序
>>> x
[1, 10, 8, 0, 7, 9, 2, 3, 5, 6, 4]
>>> x.sort(key=lambda item:len(str(item)),reverse=True)
#按指定规则排序
>>> x
[10, 1, 8, 0, 7, 9, 2, 3, 5, 6, 4]
>>> x.reverse() #逆序
>>> x
[4, 6, 5, 3, 2, 9, 7, 0, 8, 1, 10]
>>> x.sort(key=str) #转换为字符串再排序
>>> x
[0, 1, 10, 2, 3, 4, 5, 6, 7, 8, 9]
>>> x.sort() #默认排序
>>> x
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
注:sorted()函数不改变原列表的顺序
>>> x = list(range(11))
>>> import random
>>> random.shuffle(x)
>>> sorted(x,key=lambda item:len(str(item)),reverse=True)
[10, 7, 0, 8, 6, 9, 1, 4, 3, 2, 5]
>>> sorted(x,key=str)
[0, 1, 10, 2, 3, 4, 5, 6, 7, 8, 9]
>>> x
[7, 0, 8, 6, 9, 1, 4, 10, 3, 2, 5]
>>> reversed(x)
<list_reverseiterator object at 0x000001C58999C400>
>>> list(reversed(x))
[5, 2, 3, 10, 4, 1, 9, 6, 8, 0, 7]
- sorted()实现更加复杂的排序:
>>> gameresult=[['Bob',95.0,'A'],
['Alan',86.0,'C'],
['Mandy',83.5,'A'],
['rob',89.3,'E']]
>>> from operator import itemgetter
>>> sorted(gameresult,key=itemgetter(2)) #按子列表第3个元素进行升序
[['Bob', 95.0, 'A'], ['Mandy', 83.5, 'A'], ['Alan', 86.0, 'C'], ['rob', 89.3, 'E']]
>>> sorted(gameresult,key=itemgetter(2,0)) #按第3个升序,然后按第1个升序
[['Bob', 95.0, 'A'], ['Mandy', 83.5, 'A'], ['Alan', 86.0, 'C'], ['rob', 89.3, 'E']]
>>> sorted(gameresult,key=itemgetter(2,0),reverse=True)
[['rob', 89.3, 'E'], ['Alan', 86.0, 'C'], ['Mandy', 83.5, 'A'], ['Bob', 95.0, 'A']]
>>> list1 = ["what","I'm","sorting","by"]
>>> list2 = ["something","else","to","sort"]
>>> pairs = zip(list1,list2) #把两个列表中对应位置元素配对
>>> [item[1] for item in sorted(pairs,key=lambda x:x[0],reverse=True)]
['something', 'to', 'sort', 'else']
>>> sorted(x,key=lambda item:(item[1],-item[2])) #以第2个元素升序,第3个元素降序
[[2, 1, 4], [1, 2, 3], [2, 2, 1]]
>>> x = ['aaaa','bc','d','b','ba']
>>> sorted(x,key=lambda item:(len(item),item)) #先按长度排列,相同的正常排列
['b', 'd', 'ba', 'bc', 'aaaa']
内置函数对列表的操作
- max(), min(), sum(), len(),
- zip([iterable, …]):iterable一个或多个迭代器
>>> x = [1,2,3]
>>> y = [7,8,9]
>>> zip(x,y)
<zip object at 0x000001C76A723C08>
>>> list(zip(x,y))
[(1, 7), (2, 8), (3, 9)]
>>>nums = ['flower','flow','flight']
>>>for i in zip(*nums):
print(i)
('f', 'f', 'f')
('l', 'l', 'l')
('o', 'o', 'i')
('w', 'w', 'g')
- enumerate() 枚举列表元素,返回enumerate对象,enumerate对象可迭代
>>>x = [2,5,6,8,7,9,6,2,3,10]
>>>enumerate(x) #枚举列表元素,返回enumerate对象
>>> list(enumerate(x)) #enumerate对象可迭代
[(0, 2), (1, 5), (2, 6), (3, 8), (4, 7), (5, 9), (6, 6), (7, 2), (8, 3), (9, 10)]
- map(function, iterable, …):会根据提供的函数对指定序列做映射。
第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表。
>>>def square(x) : # 计算平方数
... return x ** 2
...
>>> map(square, [1,2,3,4,5]) # 计算列表各个元素的平方
[1, 4, 9, 16, 25]
>>> map(lambda x: x ** 2, [1, 2, 3, 4, 5]) # 使用 lambda 匿名函数
[1, 4, 9, 16, 25]
# 提供了两个列表,对相同位置的列表数据进行相加
>>> map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])
[3, 7, 11, 15, 19]
- reduce(function, iterable[, initializer]):函数会对参数序列中元素进行累积
>>>from functools import reduce
>>>reduce(lambda x,y:x+y,[1,2,3,4,5])
5050
- filter(function, iterable)
def is_odd(x):
return x % 2==0
newodd = filter(is_odd,[1,2,3,4,5,6,7,8,9])
print(newodd)
>>> seq = ['foo','x41','?!','***']
>>> def func(x):
... return x.isalnum() #测试x是否为数字或字母
>>> filter(func,seq) #返回filter对象
<filter object at 0x000001C76A71FEF0>
>>> [x for x in seq if x.isalnum()] #用列表推倒式实现
['foo', 'x41']
>>> list(filter(lambda x:x.isalnum(),seq)) #用lambda表达式实现
['foo', 'x41']
列表推导式:[表达式 for 变量 in 序列或迭代对象]
- 列表推导式再逻辑上相当于一个循环,只是形式更加简洁
- 实现嵌套的平铺
>>> vec = [[1,2,3],[4,5,6],[7,8,9]]
>>> [num for elem in vec for num in elem]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
- 过滤不符合体条件的元素
>>> import os
>>> [filename for filename in os.listdir('.') if filename.endswith('.py')]
['1.py', 'ss.py']
# 列出当前文件的所有python文件
>>> alist = [-1,2,3,-4,-5,6]
>>> [i for i in alist if i>0]
[2, 3, 6]
- 实现多个循环
>>> [(x,y) for x in [1,2,3] for y in [1,3,4] if x!=y]
[(1, 3), (1, 4), (2, 1), (2, 3), (2, 4), (3, 1), (3, 4)]
- 实现矩阵转换
>>> matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
>>> [[raw[i] for raw in matrix]for i in range(4)]
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
#也可以用zip(),map()实现
>>> list(map(list,zip(*matrix)))
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
- 可以使用函数或复杂表达式
>>> def f(v):
... if v%2 ==0:
... v=v**2
... else:
... v=v+1
... return v
...
>>> print([f(v) for v in [2,3,4,-1] if v>0])
[4, 4, 16]
>>> print([v**2 if v%2 == 0 else v+1 for v in [2,3,4,-1] if v>0])
[4, 4, 16]
- 支持文件对象迭代
>>>fp = open('C:\\install.log','r')
>>>print([line for line in fp])
>>>fp.close()
- 生成100以内的素数
>>>import math
>>> [p for p in range(2,100) if 0 not in [p%d for d in range(2,int(math.sqrt(p))+1)]]
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
切片
- 切片使用2个冒号分隔的3个数字来完成:
第一个数字表示切片开始位置(默认为0)。
第二个数字表示切片截止(但不包含)位置(默认为列表长度)。
第三个数字表示切片的步长(默认为1),当步长省略时可以顺便省略最后一个冒号。
>>> aList = [3, 4, 5, 6, 7, 9, 11, 13, 15, 17]
>>> aList[::] #返回包含所有元素的新列表
[3, 4, 5, 6, 7, 9, 11, 13, 15, 17]
>>> aList[::-1] #逆序的所有元素
[17, 15, 13, 11, 9, 7, 6, 5, 4, 3]
>>> aList[::2] #偶数位置,隔一个取一个
[3, 5, 7, 11, 15]
>>> aList[1::2] #奇数位置,隔一个取一个
[4, 6, 9, 13, 17]
>>> aList[3::] #从下标3开始的所有元素
[6, 7, 9, 11, 13, 15, 17]
>>> aList[3:6] #下标在[3, 6)之间的所有元素
[6, 7, 9]
>>> aList[0:100:1] #前100个元素,自动截断
[3, 4, 5, 6, 7, 9, 11, 13, 15, 17]
>>> aList[100:] #下标100之后的所有元素,自动截断
[]
>>> aList[100] #直接使用下标访问会发生越界
IndexError: list index out of range
- 使用切片对列表元素进行增、删、改
>>> aList = [3, 5, 7]
>>> aList[len(aList):]
[]
>>> aList[len(aList):] = [9] #在列表尾部增加元素
>>> aList
[3, 5, 7, 9]
>>> aList[:3] = [1, 2, 3] #替换列表元素
>>> aList
[1, 2, 3, 9]
>>> aList[:3] = [] #删除列表元素
>>> aList
[9]
>>> aList = list(range(10))
>>> aList
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> aList[::2] = [0]*(len(aList)//2) #替换列表元素
>>> aList
[0, 1, 0, 3, 0, 5, 0, 7, 0, 9]
>>> aList[3:3] = [4, 5, 6] #在列表指定位置插入元素
>>> aList
[0, 1, 0, 4, 5, 6, 3, 0, 5, 0, 7, 0, 9]
>>> len(aList)
13
>>> aList[20:30] = [3]*2 #这样也可以在尾部追加元素,注意切片范围
>>> aList
[0, 1, 0, 4, 5, 6, 3, 0, 5, 0, 7, 0, 9, 3, 3]
- 注意:使用切片修改列表元素值时,如果左侧切片是连续的那么等号两侧的列表长度可以不一样;如果左侧切片不连续,则右侧列表中元素个数必须与左侧相等;使用del命令和切片删除列表中部分元素时,切片可以不连续。
>>> x = list(range(10))
>>> x[::2] = [3,5] #等号两侧不等长,抛出异常
ValueError: attempt to assign sequence of size 2 to extended slice of size 5
>>> x[::2] = [1, 1, 1, 1, 1] #等长,可以执行
>>> x
[1, 1, 1, 3, 1, 5, 1, 7, 1, 9]
>>> del x[::2] #可以删除列表中不连续的元素
>>> x
[1, 3, 5, 7, 9]
元组
- 元组属于不可变序列,一旦创建,没有任何方法修改元组中的元素,也无法增加或删除元素
>>> x = (1,2,3)
>>> x
(1, 2, 3)
>>> type(x)
<class 'tuple'>
>>> x = (3)
>>> x
3
>>> x=(3,) #如果元组只有一个元素,需在后面加逗号
>>> x
(3,)
>>> x = tuple() #空元组
>>> x
()
>>> tuple(range(5))
(0, 1, 2, 3, 4)
- 如果元组中包含可变序列,就变得复杂了
>>> x = ([1,2],3) #创建包含列表的元组
>>> x[0][0] = 5 #修改元组中列表的值
>>> x
([5, 2], 3)
>>> x[0].append(8) #为元组中的列表增加元素
>>> x
([5, 2, 8], 3)
>>> x[0] = x[0] +[10] #试图修改元组中的值,失败
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
生成器推导式
- 当所有元素访问结束后,如果需要重新访问其中元素,必须重新创建该生成器对象
>>> g = ((i+2)**2 for i in range (10)) #创建生成器对象
>>> g
<generator object <genexpr> at 0x0000016CADF15A40>
>>> tuple(g) #将生成器对象转换为元组
(4, 9, 16, 25, 36, 49, 64, 81, 100, 121)
>>> list(g) #生成器对象已遍历完,没有元素了
[]
>>> g = ((i+2)**2 for i in range (10))
>>> g.__next__() #使用生成器对象的__next__()方法获取元素
4
>>> g.__next__() #获取下一个元素
9
>>> next(g) #使用内置函数next()获取生成器对象中的元素
16
>>> next(g) #获取下一个元素
25
>>> g = ((i+2)**2 for i in range (10)) #使用循环直接遍历
>>> for item in g:
... print(item,end=' ')
...
4 9 16 25 36 49 64 81 100 121
- 包含yield语句的函数可以用来创建可迭代的生成器对象
>>> def f():
... a,b=1,1 #序列解包,同时为多个元素赋值
... while True:
... yield a #暂停执行,需要时在产生一个新元素
... a,b=b,a+b #序列解包,继续生成新元素
...
>>> a=f()
>>> for i in range(10): #斐波那契数列前十个元素
... print(a.__next__(),end=' ')
...
1 1 2 3 5 8 13 21 34 55
>>> for i in f():
... if i > 100: #斐波那契数列第一个大于100的元素
... print(i,end=' ')
... break
...
144
>>> a = f()
>>> next(a)
1
>>> next(a)
1
>>> next(a)
2
>>> next(a)
3
字典
- dict中的key可以是python中的任意不可变数据,如整数,实数,复数,字符串,元组等,但不能使用列表、集合、自带你或其他可变类型作为字典的键,字典的键不允许重复,而‘值’是可变的。
- 字典创建及元组添加
>>>a_dict={'server':'db.diveintopython3.org',database':'mysql'} >>>a_dice {'database':'mysql','server':'db.diveintopython3.org'}
- 也可使用内置函数dict()通过已有数据快速创建字典
>>>keys = ['a','b','c'] >>>values = [1,2,3] >>>dictionary = dict(zip(keys,values)) >>>print(dictionary) ['a':1,'b':2,'c':3]
- 还可用dict()根据给定的“键:值”来创建字典
>>>d = dict(name='LiMing',age=18) >>>d {'age':18,'name':'LiMing'}
- 增加修改删除数据
>>>aDict {'age':18,'name':'LiMing',sex:'male'} >>> aDict['age']=20 #修改元素值 >>>aDict['address']='SDIBT' #添加新元素 >>>aDict.update({'age':28,'a':56}) #修改'age'的值,同时添加元素'a':56 >>>del aDect['age'] #删除字典元素 >>>del aDect #删除整个字典 >>>aDicr={'age':37,'score':[98,97],'name':'LiMing','sex':'male') >>>aDict.popitem() #弹出一个元素,空字典会抛出异常 {'age',37} >>>aDict.pop('sex') #弹出指定元素 >>>aDict {'score':[98,97],'name':'LiMing'}
集合
- 集合是无序可变序列,使用一对大括号作为界定符,元素之间用逗号分隔,同一集合 的每个元素都是唯一的,元素之间不允许重复。
- 创建集合
>>>a = {1,2} >>>a {1,2} >>>a_set = set(range(1,5)) >>>a_set {1,2,3,4} >>>b_set=set({0,1,2,3,0,1,2,3,4,5}) #转换时自动去点重复元素 >>>b_set {0,1,2,3,4,5}
- 集合元素增加与删除
>>> s = {1,2,3} >>> s.add(3) #添加元素,重复元素自动忽略 >>> s {1, 2, 3} >>> s.update({3,4}) #更新当前集合,自动忽略重复元素 >>> s {1, 2, 3, 4} >>> s.discard(5) #删除元素,不存在则忽略 >>> s {1, 2, 3, 4} >>> s.remove(5) #删除元素,不存在就抛出异常 Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 5 >>> s.pop() #删除并返回一个元素 1
- 集合运算
>>> a_set=set([8,9,10,11,12,13]) >>> b_set={0,1,2,3,7,8} >>> a_set|b_set #并集 {0, 1, 2, 3, 7, 8, 9, 10, 11, 12, 13} >>> a_set.union(b_set) #并集 {0, 1, 2, 3, 7, 8, 9, 10, 11, 12, 13} >>> a_set&b_set #交集 {8} >>> a_set.intersection(b_set) #交集 {8} >>> a_set.difference(b_set) #差集 {9, 10, 11, 12, 13} >>> a_set-b_set {9, 10, 11, 12, 13} >>> a_set.symmetric_difference(b_set) #对称差集 {0, 1, 2, 3, 7, 9, 10, 11, 12, 13} >>> a_set^b_set {0, 1, 2, 3, 7, 9, 10, 11, 12, 13} >>> x={1,2,3} >>> y={1,2,5} >>> z={1,2,3,4,} >>> x<y #比较集合大小 False >>> x<z True >>> y<z False >>> x.issubset(y) #测试是否为子集 False >>> x.issubset(z) True