参考
-
《简明python教程》
Note:
- 更多连载请查看【python】
最近一次修订时间为 2020-11-04
打了激素的数组
图片来自:https://www.bilibili.com/video/av20982396/?p=7
1 列表的创建
列表的创建用[ ],列表可以嵌套使用,即列表中包含其它数据类型,比如包含list(列表)、tuple(元组)、dict(字典)、set(集合)
list1 = [1,2,3,4,5] #创建列表
print ('list1:',list1)
list2 = ['a','b','c','d'] #列表中的数据类型可以是相同的,都是字符串
print ('list2:',list2)
list3 = [1,2.33,'Python','a'] #列表中的数据类型也可以是不同的,整型、浮点型、字符串
print ('list3:',list3)
list4 = [1, 2.33, 'Python', 'a',list3]#列表里还可以嵌套列表,列表中有列表
print ('list4:',list4)
list5 = []#创建空列表
print ('list5:',list5)
print ("list5's type is:",type(list5))
output
list1: [1, 2, 3, 4, 5]
list2: ['a', 'b', 'c', 'd']
list3: [1, 2.33, 'Python', 'a']
list4: [1, 2.33, 'Python', 'a', [1, 2.33, 'Python', 'a']]
list5: []
list5's type is: <class 'list'>
下面详细来看看list的嵌套结构
set1 = {1,2,3,4,5}
print (type(set1))
dict1 = {'a':1}
print (type(dict1))
tuple1 = ('a','b','c')
print (type(tuple1))
list7 = [1,2,3,4,5]
print (type(list7))
list8 = [set1,dict1,tuple1,list7]
print (type(list8))
output
<class 'set'>
<class 'dict'>
<class 'tuple'>
<class 'list'>
<class 'list'>
多维列表的创建
a = [[1,2],[3,4]]
type(a)
output
list
多重赋值
data_1, data_2, data_3, data_4 = [], [], [], []
# 或者使用列表推导式,见本文第四小节
data_1, data_2, data_3, data_4 = [[] for i in range(4)]
print(data_1, data_2, data_3, data_4)
output
[] [] [] []
配合循环来创建
list1 = [i for i in range(10)]
print(list1)
list2 = list(range(10))
print(list2)
output
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
2 一些列表的基本操作
2.1 通过索引取出列表中的元素
索引从0开始
2.2 连接(+)、复制(*)、求长度(len())
- 连接用 +
- 复制用 *
- 求长度用 len()
list1 = [1, 2, 3, 4, 5]
list2=['a', 'b', 'c', 'd']
print ('list1+list2:',list1+list2)#使用加号连接列表
print('list1*3:',list1*3) #列表复制阵列,把列表复制三遍
print ("list1+list2's length is:",len(list1+list2)) #求列表长度
结果为
list1+list2: [1, 2, 3, 4, 5, 'a', 'b', 'c', 'd']
list1*3: [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
list1+list2's length is: 9
2.3 检查列表中是否存在某个元素(in)
用 in
2.4 删除列表(del)
1)用 del
删除整个列表
2)删除列表中指定的元素
list2=['a', 'b', 'c', 'd']
del list2[2] #删除列表中索引为 i 的元素
print(list2)
结果为
['a', 'b', 'd']
3)删除子列表
list1 = [0,1,2,3,4,5,6]
del list1[1:3]#删除列表的子列表
print(list1)
结果为
[0, 3, 4, 5, 6]
看看更为灵活的删除
a = [1,2,3,4,5]
del a[2::2] # 从 inde 2 开始隔 2 删一个
print(a)
output
[1, 2, 4]
2.5 求最大值最小值(max、min)
用 max
和 min
list2=['a', 'b', 'c', 'd']
print (max(list2)) #返回列表中最大的值,max(列表名)
print (min(list2))#返回列表中最小的值
结果为
d
a
列表中元素如果不能比较的话,使用max就会报错
2.6 切片
列表切片指的是将列表的一部分切出来,有点像字符串切片。并且不改变原列表的内容!!!
列表切片的形式是:
list[起始索引:终止索引(不包含):步长间隔]
Note:步长可以是负值,切片切出来的还是列表
list1 = [0,1,2,3,4,5,6,7,8]
print ('list1[5:8]:',list1[5:8])#步长省略则默认为1
print ('list1[1:6:2]:',list1[1:6:2]) #步长为2
print ('list1[3:]:',list1[3:]) #取索引3到最后
print ('list1[:5]:',list1[:5]) #从头取到索引5(索引5取不到)
print ('list1[::2]:',list1[::2]) #取所有,步长为2
print ('list1[3:-1]:',list1[3:-1]) #从索引3取到倒数第一个(倒数第一个取不到)
print ('list1[:]:',list1[:]) #取所有的
print ('list1[::-1]:',list1[::-1]) #逆序列表
print ('list1[8:2:-2]:',list1[8:2:-2]) #逆序取,步长为2
结果为
list1[5:8]: [5, 6, 7]
list1[1:6:2]: [1, 3, 5]
list1[3:]: [3, 4, 5, 6, 7, 8]
list1[:5]: [0, 1, 2, 3, 4]
list1[::2]: [0, 2, 4, 6, 8]
list1[3:-1]: [3, 4, 5, 6, 7]
list1[:]: [0, 1, 2, 3, 4, 5, 6, 7, 8]
list1[::-1]: [8, 7, 6, 5, 4, 3, 2, 1, 0]
list1[8:2:-2]: [8, 6, 4]
Note:一定要注意,索引区间为[A,B)半闭半开,-1逆序第一个元素
Question:llist1[0]和list1[0:1]一样吗?
结果是不一样的
llist1[0]输出列表的第零个元素
list1[0:1]输出的是包含列表第零个元素的列表
继续上才艺
[m:n] 取a[m]~a[n-1] 之间的内容,m \ n 可以为负,m>n 时返回空
[m::n] 取a[m] 开始,每跳 n 个取一个,n 为负数逆取,n 为负时,m 为空则置为 0,n为正时 m 为空则置为 -1
a = list(range(10))
print(a)
print(a[::2]) # [0, 2, 4, 6, 8]
print(a[::-1]) # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0],到第一个元素停止
print(a[::-2]) # [9, 7, 5, 3, 1]
print(a[3::1]) # [3, 4, 5, 6, 7, 8, 9]
print(a[3::2]) # [3, 5, 7, 9]
print(a[3::3]) # [3, 6, 9]
print(a[3::-1]) # [3, 2, 1, 0]
print(a[8::-2]) # [8, 6, 4, 2, 0]
print(a[8::-3]) # [8, 5, 2]
output
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 2, 4, 6, 8]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
[9, 7, 5, 3, 1]
[3, 4, 5, 6, 7, 8, 9]
[3, 5, 7, 9]
[3, 6, 9]
[3, 2, 1, 0]
[8, 6, 4, 2, 0]
[8, 5, 2]
list1 = [1, 2, 3, 4, 5, 6, 8, 1, 2, 3, 6, 9, 8, 6]
print(list1[::])
print(list1[::2])
output
[1, 2, 3, 4, 5, 6, 8, 1, 2, 3, 6, 9, 8, 6]
[1, 3, 5, 8, 2, 6, 8]
起始索引:终止索引 就是 slice(起始索引,终止索引) 的缩写
s = [1,2,3,4]
print(s[1:3])
print(s[slice(1,3)]) # 1:3 就是 slice(1,3) 的缩写
output
[2, 3]
[2, 3]
2.7 修改元素
list1 = [0,1,2,3,4,5,6,7,8]
list1[2] = 'Python' # 修改列表元素
print (list1)
list1[4:6] = ['a','b','c','d']
print (list1)
结果为
[0, 1, 'Python', 3, 4, 5, 6, 7, 8]
[0, 1, 'Python', 3, 'a', 'b', 'c', 'd', 6, 7, 8]
2.8 对列表元素循环
list1 = [1,2,3,4,5]
for i in list1:
print(i)
结果为
1
2
3
4
5
2.9 copy
id() 方法用于获取对象的内存地址
list1 = [0,1,2,3,4,5,6,7,8]
print (id(list1))
print (id(list1[:]))
list2 = list1[:]
print (id(list2))
list3 = list1[:]
print (id(list3))
大家多会觉得,这四个 id 应该都一样,可事实如下:
1863546661320
1863546661512
1863546661384
1863545252296
四个 id 都不一样,以上是为什么呢?
涉及到 python 的浅复制和深复制,因为python的赋值更像是贴标签
list2 = list1
list3 = list1[:]
上面两种复制方法差别很大
list2 是浅层复制(贴标签),会跟随 list1 的改变而改变,list3 是深复制,这才是我们真正意义上的复制
list1 = [0,1,2,3,4,5,6,7,8]
print(id(list1))
list2 = list1
print(id(list2))
list3 = list1[:]
print(id(list3))
output
1863546690184
1863546690184
1863545219976
1)直接复制
a = b 直接复制
a = [1,2,3,4]
b = a # 复制
print(id(a)==id(b))
for i in range(len(a)):
print(id(a[i])==id(b[i]))
a[0] = 5
print(a)
print(b)
b[0]=1
print(a)
print(b)
output
True
True
True
True
True
[5, 2, 3, 4]
[5, 2, 3, 4]
[1, 2, 3, 4]
[1, 2, 3, 4]
会发现,a 和 b 的 id 地址是一样的,a 和 b 中每一个元素的 id 都是一样的,改变 a 和 b 任何一个变量,对方都会改变,这就尴尬了,就像花钱买回来的玩具汽车,别人也有个遥控器!
2)copy.copy() 浅复制
当使用浅拷贝时,python只是拷贝了最外围的对象本身,内部的元素都只是拷贝了一个引用而已。看代码:
import copy
a = [1,2,3,4]
b = copy.copy(a)# 复制
print(id(a)==id(b))
for i in range(len(a)):
print(id(a[i])==id(b[i]))
a[0] = 5
print(a)
print(b)
b[0]=2
print(a)
print(b)
output
False
True
True
True
True
[5, 2, 3, 4]
[1, 2, 3, 4]
[5, 2, 3, 4]
[2, 2, 3, 4]
a 和 b 的 id 不一样了,虽然,a 和 b 每个元素的 id 一样,但是 a 和 b 的改变不会影响到对方,这样似乎解决了 1)中的缺点,但是再看看下面的例子
import copy
a = [1,2,[3,4]]
b = copy.copy(a)# 复制
print(id(a)==id(b))
print('\nfirst layer')
for i in range(len(a)):
print(id(a[i])==id(b[i]))
print('\nsecond layer')
for i in range(len(a[2])):
print(id(a[2][i])==id(b[2][i]))
output
False
first layer
True
True
True
second layer
True
True
a 和 b 的 id 不一样,但是每一个元素的 id 都一样,改变 第一层的元素试试
a[0] = 5
print(a)
print(b)
b[0] = 2
print(a)
print(b)
output
[5, 2, [3, 4]]
[1, 2, [3, 4]]
[5, 2, [3, 4]]
[2, 2, [3, 4]]
a 和 b 不会相互影响
改改第二层的元素试试
import copy
a = [1,2,[3,4]]
b = copy.copy(a)# 复制
print(a)
print(b)
a[2][0] = 8
print(a)
print(b)
b[2][0]=2
print(a)
print(b)
output
[1, 2, [3, 4]]
[1, 2, [3, 4]]
[1, 2, [8, 4]]
[1, 2, [8, 4]]
[1, 2, [2, 4]]
[1, 2, [2, 4]]
oh,no 无良商家,卖门留一把门钥匙(哈哈哈,开玩笑的,想表达两者关系绑定了),这就是浅层复制,第一层独立了,第二层藕断丝连!我们用深层复制来斩断这个情丝吧!!!
3)copy.deepcopy() 深复制
deepcopy
对外围和内部元素都进行了拷贝对象本身,而不是对象的引用。
import copy
a = [1,2,[3,4]]
b = copy.deepcopy(a)# 复制
print(id(a)==id(b))
print('\nfirst layer')
for i in range(len(a)):
print(id(a[i])==id(b[i]))
print('\nsecond layer')
for i in range(len(a[2])):
print(id(a[2][i])==id(b[2][i]))
output
False
first layer
True
True
False
second layer
True
True
可以看出,第二层的 id 不同了,但是第二层列表里面的每个元素的 id 还是相同的!
再测试一下
import copy
a = [1,2,[3,4]]
b = copy.deepcopy(a)# 复制
print(a)
print(b)
a[2][0] = 8
print(a)
print(b)
b[2][0]=2
print(a)
print(b)
output
[1, 2, [3, 4]]
[1, 2, [3, 4]]
[1, 2, [8, 4]]
[1, 2, [3, 4]]
[1, 2, [8, 4]]
[1, 2, [2, 4]]
ok,有自主权了,可以叫做出师了吗?或者叫农夫与蛇,忘恩负义,恩断义绝,哈哈哈,完全和前任划清界限的感觉!
3 列表的一些常用方法
- 添加:append、extend、insert
- 删除:remove、del、pop
全部的BIF可以用dir查看
dir(list)
3.1 append
list.append(obj)
,在列表末尾添加新的对象
list1 = [0,1,2,3,4,5,6,7,8]
print (list1)
list1.append('Kobe') #list.append( obj ) 在列表末尾添加新的对象
print (list1)
list1.append(1)
print (list1)
结果为
[0, 1, 2, 3, 4, 5, 6, 7, 8]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 'Kobe']
[0, 1, 2, 3, 4, 5, 6, 7, 8, 'Kobe', 1]
3.2 count
list.count(obj)
,统计某个元素在列表中出现的次数
list1 = [1,2,1,2,1]
print (list1.count(1)) #list.count( obj ) 统计某个元素在列表中出现的次数
print (list1.count('1'))
结果为
3
0
3.3 extend
list.extend(seq)
,在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
list2 = [0,1,2,3,4]
print (list2)
list2.extend('a') #list.extend(seq) 在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
print (list2)
list2.extend(['b',[1,2,3]])#extend添加单个元素和append很像,但他可以一次添加更多元素,元素可以是列表
print (list2)
结果为
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4, 'a']
[0, 1, 2, 3, 4, 'a', 'b', [1, 2, 3]]
那么问题来了,append和extend有什么区别呢?看如下的例子就知道了
list1 = [1,2,3]
list1.append([4,5,6])
print (list1)
list1 = [1,2,3]
list1.extend([4,5,6])
print (list1)
结果为
[1, 2, 3, [4, 5, 6]]
[1, 2, 3, 4, 5, 6]
这两个方法功能类似,但是在处理多个列表的时候,这两个方法的处理结果是完全不相同的。想一次性给某一个列表添加多个元素,用 extend,以列表的形式添加!
灵活运用,例如将列表的所有元素,包括子列表,都展开成一个列表
list1 = [1,[2],3,[4,5]]
result = []
for item in list1:
if isinstance(item,list):
result.extend(item)
else:
result.append(item)
print(result)
output
[1, 2, 3, 4, 5]
3.4 index
list.index(obj)
,从列表中找出某个值第一个匹配项的索引位置
list1 = [1,2,1,4,1]
print (list1.index(1)) #list.index(obj)从列表中找出某个值第一个匹配项的索引位置
print (list1.index(4))
output
0
3
也可以返回某一个区间内,第一次出现的元素索引
list1 = [1,2,1,4,1]
print (list1.index(1,1,3)) #list.index(obj)从列表中找出某个值第一个匹配项的索引位置,范围,1-3(0是第一个)
结果为
2
3.5 insert
list.insert(index, obj)
,将对象插入列表,查到指定index(索引)的前面
list1 = [0,1,2,3,4]
list1.insert(2,'b')#list.insert(index, obj)将对象插入列表
print (list1)
list1.insert(0,'a')
print (list1)
结果为
[0, 1, 'b', 2, 3, 4]
['a', 0, 1, 'b', 2, 3, 4]
也可以插入其它的数据结构,例如列表
list1 = [0,1,2,3,4]
list1.insert(4,['b','c'])#也可以插入一个列表
print (list1)
结果为
[0, 1, 2, 3, ['b', 'c'], 4]
补充,也可以通过索引来实现插入
a = [1,2,3,4,5]
a[:0] = [-1,0]
print(a)
output
[-1, 0, 1, 2, 3, 4, 5]
3.6 pop
list.pop(obj=list[-1])
,移除列表中的一个元素(默认最后一个元素),并且返回该元素的值
list1 = [0,1,2,3,4,5]
a = list1.pop()#list.pop(obj=list[-1])移除列表中的一个元素(默认最后一个元素),并且返回该元素的值
print (a)
print (list1)
list1.pop(2)#也可以指定删除的索引
print (list1)
结果为
5
[0, 1, 2, 3, 4]
[0, 1, 3, 4]
3.7 remove
list.remove(obj)
,移除列表中某个值的第一个匹配项
list1 = [0,1,2,3,4,2,2]
list1.remove(2)#list.remove(obj)移除列表中某个值的第一个匹配项
print (list1)
结果为
[0, 1, 3, 4, 2, 2]
补充
for i in a:
if i==x:
a.remove(i)
删不干净,索引变了
用 for 发起任何形式的遍历时,它的遍历顺序是一开始就确定的,而在遍历中删除了元素导致了当前索引的变化。整个列表的元素向前移动,但i却在最初就确定了,所以导致漏删元素。
for i in a[:]:
if i==x:
a.remove(i)
这样就可以删干净
3.8 reverse(和 list1[::-1] 效果一样)
list.reverse(),反向列表中元素
list1 = [0,1,2,3,4,5]
list1.reverse()#list.reverse()反向列表中元素
print (list1)
结果为
[5, 4, 3, 2, 1, 0]
和 list1[::-1]
效果一样
3.9 sort
list.sort([func])
,对原列表进行排序,修改了原列表
list5 = [2,1,4,5,3,6,8,7,0]
list5.sort()#list.sort([func])对原列表进行排序
print (list5)
结果为
[0, 1, 2, 3, 4, 5, 6, 7, 8]
默认为升序,降序的操作如下
list1 = [2,1,4,5,3,6,8,7,0]
list1.sort(reverse = True)
print (list1)
结果为
[8, 7, 6, 5, 4, 3, 2, 1, 0]
也可以对字符串进行排序,按照ASCII的顺序来,数字 < 大写字母 < 小写字母
list1 = ['a','A','1','Python','python']
list1.sort()
print(list1)
结果为
['1', 'A', 'Python', 'a', 'python']
sort 与 sorted 的区别
list1 = [6, 3, 8, 9, 10, 7]
list2 = list1.sort()
print(list1)
print(list2)
list2 = sorted(list1)
print(list1)
print(list2)
output
[3, 6, 7, 8, 9, 10]
None
[3, 6, 7, 8, 9, 10]
[3, 6, 7, 8, 9, 10]
看下 sort 和 sorted 的介绍,就可以发现,一个是 list 对象中的一个方法,没有返回值,一个是 BIF,返回 list
list
def sort(self,
*,
key: Optional[(_T) -> Any] = ...,
reverse: bool = ...) -> None
builtins
def sorted(__iterable: Iterable[_T],
*,
key: Optional[(_T) -> Any] = ...,
reverse: bool = ...) -> List[_T]
和 sort 一样,print 也是没有返回值的
a = print('bryant')
type(a)
output
bryant
NoneType
sort 的有个 key 参数,用法非常灵活
list1 = list("Python is my favorite programming language".split(" "))
print(list1) # 原始列表
list1.sort()
print(list1) # 默认排序
list1.sort(key=len)
print(list1) # 根据长度排序
list1.sort(key=str.lower)
print(list1) # 区分大小写排序
output
['Python', 'is', 'my', 'favorite', 'programming', 'language']
['Python', 'favorite', 'is', 'language', 'my', 'programming']
['is', 'my', 'Python', 'favorite', 'language', 'programming']
['favorite', 'is', 'language', 'my', 'programming', 'Python']
3.10 配合 enumerate
animals = ['dog','cat','fish']
for i,j in enumerate(animals):
print(i,j)
output
0 dog
1 cat
2 fish
3.11 zip
zip
函数接受任意多个(包括0个和1个)序列作为参数,合并后返回一个 tuple
列表,请看示例:
a = [1,2,3]
b = [4,5,6]
print(zip(a,b))
print(type(zip(a,b)))
c = list(zip(a,b))
print(c)
output
<zip object at 0x0000019D86D724C8>
<class 'zip'>
[(1, 4), (2, 5), (3, 6)]
zip 0 个序列
d = list(zip())
d
output
[]
zip 一个序列
for i in zip(a):
print(i)
output
(1,)
(2,)
(3,)
zip 两个序列
for i,j in zip(a,b):
print(i,j)
output
1 4
2 5
3 6
zip 三个序列
for i,j,z in zip(a,a,b):
print(i,j,z)
output
1 1 4
2 2 5
3 3 6
4 列表推导式或解析式
List comprehensions,灵感取自函数式编程语言Haskell。Ta 是一个非常有用和灵活的工具,可以用来动态的创建列表,语法如下:
[有关 A 的表达式 for A in B]
例如,生成一个列表,元素是1~10的平方。
[i**2 for i in range(1,11)]#一行代码搞定!是不是很优雅
和 for……in……配合生成列表, 再看一些例子,熟悉下这种操作
[m+n for m in 'ABC' for n in'abc']
结果为
['Aa', 'Ab', 'Ac', 'Ba', 'Bb', 'Bc', 'Ca', 'Cb', 'Cc']
[x**2 for x in range(1,11) if x%3==0]
结果为
[9, 36, 81]
list1 = [(x, y) for x in range(10) for y in range(10) if x%2==0 if y%2!=0]
print (list1)
结果为
[(0, 1), (0, 3), (0, 5), (0, 7), (0, 9), (2, 1), (2, 3), (2, 5), (2, 7), (2, 9), (4, 1), (4, 3), (4, 5), (4, 7), (4, 9), (6, 1), (6, 3), (6, 5), (6, 7), (6, 9), (8, 1), (8, 3), (8, 5), (8, 7), (8, 9)]
再看看更为灵活的用法
list1 = ["FizzBuzz" if i%3 == i%5 == 0
else "Fizz" if i%3 == 0
else "Buzz" if i%5 == 0
else i for i in range(1,20)]
print(list1)
output
[1, 2, 'Fizz', 4, 'Buzz', 'Fizz', 7, 8, 'Fizz', 'Buzz', 11, 'Fizz', 13, 14, 'FizzBuzz', 16, 17, 'Fizz', 19]
补充,同样的 set 和 dict 也有解析式
list1 = [1, 2, 3, 4, 5, 2, 5, 1, 4, 8]
set1 = { x for x in list1 if x % 2 == 0 }
print(type(set1))
print(set1)
dict1 = { x: x % 2 == 0 for x in range(1, 11) }
print(type(dict1))
print(dict1)
output
<class 'set'>
{8, 2, 4}
<class 'dict'>
{1: False, 2: True, 3: False, 4: True, 5: False, 6: True, 7: False, 8: True, 9: False, 10: True}
Note: 更多连载请查看【python】