ljzsdut
GitHubToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage

08 列表

Python的列表对象是这个语言提供的最通用的序列。列表是容器类型,存储的是任意类型的对象的有序集合。

与字符串不同的是,列表没有固定的大小,其大小是可变的,是一个可变对象,支持原处修改,修改列表后不会创建一个新的列表。列表中存储的是元素的引用,修改列表修改的是引用,而不是修改的对象。

列表的表达式符号为中括号([ ]),通过index和切片能够访问和修改列表元素。

定义

list = [1,2,3,4,'nihao',5]  #使用[]定义列表。列表可以嵌套
list1='zhangsan lisi wanger mazi'.split()		#使用字符串的方法定义列表

列表的操作与方法

修改

  1. 通过索引修改指定的索引的元素:
list[2] = 32
  1. 通过分片修改指定的分片:分片顾头不顾尾
list[2:4] = []            #删除元素操作,等同于del(list[2:4])
list[2:4] = ['m','n','x','y']    #修改操作

【说明】:切片方法替换的是元素,而不是将切片[2:4]替换成列表

  1. 通过del()语句删除指定元素:
del(list[2:4])
  1. 通过加号运算连接列表:(注意加号运算符前后要有空格,原列表不变)
>>> list1=['i','love','you']
>>> list2 = ["hello","world"]
>>> list3= list1 + list2
>>> print list3
['i', 'love', 'you', 'hello', 'world']

添加元素:append、extend、insert

1、append(x):将x对象整体作为一个元素追加到列表中

>>> list=[1,2,3]
>>> list
[1, 2, 3]
>>> list.append(4)
>>> list
[1, 2, 3, 4]
>>> list.append([5,6])
>>> list
[1, 2, 3, 4, [5, 6]]

2、extend(x):x若为列表,将列表元素在尾部逐一加入;若为字典,将字典key值在尾部逐一加入

>>> lia = ['aa', 1, 'bb', None]
>>> lib = ['cc', 2, {'dd': 3}]
>>> lia.extend(lib)
>>> lia
['aa', 1, 'bb', None, 'cc', 2, {'dd': 3}]


>>> lia = ['aa', 1, 'bb', None]
>>> lib = {'dd': 3, 'ee': 44}
>>> lia.extend(lib)
>>> lia
['aa', 1, 'bb', None, 'dd', 'ee']

3、list.insert(index,object) :在指定的index前插入整个对象object

>>> list1=['i','love','you']
>>> list2=['hello','world']
>>> list1.insert(1,list2)
>>> print list1
['i', ['hello', 'world'], 'love', 'you']

删除元素:pop、remove、clear、del()

1、del(list[2:4]):del语句删除指定元素

del(list[2:4])  #等同于list[2:4] = [] 

【说明】:list[2:4] = []切片方法替换的是元素(多值赋值a,b=c,d),而不是将切片[2:4]替换成列表

2、list.pop([index]) :按索引删除。弹出(删除)指定index的值,并返回该值弹出的值。默认弹出最后一个元素。作用类似del()语句

>>> list=[1,2,3,4]
>>> list.pop(2)
3
>>> list
[1, 2, 4]
>>> list.pop()
4

3、list.remove(value) :按值删除。如果value有多个,则删除list中首次出现的value值

>>> list=[1,2,3,4,3,2,1]
>>> list.remove(2)
>>> list
[1, 3, 4, 3, 2, 1]

4、list.clear() 清除列表的所有元素,列表成为空列表

查找索引、统计数量

1、list.index(value) 返回list中value首次出现的索引号

2、list.count(value) 统计list中value出现的次数

>>> list1=[1,2,3,1,2,3,2,1]
>>> list1.count(2)
3
>>> list1.index(3)
2

排序、翻转

列表排序操作按照ASCII排序:数字<大写字母<小写字母

1、list.sort() 将list排序(升序),原处修改,没有返回值。

2、list.reverse() 将list各元素进行反转排序(而不是降序排序),原处修改,没有返回值。

>>> list1=['bb','aa','cc']
>>> list1.sort()
>>> list1
['aa', 'bb', 'cc']
>>> list1.reverse()
>>> print list1
['cc', 'bb', 'aa']

列表运算:拼接、成员判断

list1+list2 :连接两个列表,返回一个新的列表

list1*3 :等同于list1+list1+list1

in :成员关系判断符,返回bool值。用法:obj in container ,例如 22 in list1

not in :用法:obj not in container

列表引用

Python中,赋值操作总是储存对象的引用,而不是这些对象的拷贝。这点与Golang不同,Golang使用的值的拷贝。所以Python中,如果2个变量引用了同一个对象,通过其中一个变量对该对象进行修改,会影响另一个变量的值。

>>> list1=[1,2,3]
>>> list2=list1
>>> list2.append(4)
>>> list1
[1, 2, 3, 4]
>>> list2
[1, 2, 3, 4]

列表拷贝

列表的拷贝分为浅拷贝深拷贝

  • 浅拷贝:不能够复制嵌套的数据结构,只对第一层进行拷贝,第二层拷贝地址。
>>> l=[11,22,33]
>>> l1=[1,2,3]
>>> l1.append(l)
>>> l1
[1, 3, 5, [11, 22, 33]]
>>> l2=l1[:]  #浅拷贝,等同于l2 = copy.copy(l1)、l2=l1.copy() 
>>> l2
[1, 3, 5, [11, 22, 33]]
>>> l1[0]=7
>>> l1
[7, 3, 5, [11, 22, 33]]
>>> l2
[1, 3, 5, [11, 22, 33]]
>>> l1[3][1]=55
>>> l1
[7, 3, 5, [11, 55, 33]]
>>> l2
[1, 3, 5, [11, 55, 33]]
  • 深拷贝:复制嵌套的数据结构,对所有层进行拷贝,(注意,对于不可变对象(数字和字符串)不会进行拷贝,因为不可变对象是安全的,只有当修改它们时,才会进行拷贝操作)
>>> l=[11,22,33]
>>> l1=[1,2,3]
>>> l1.append(l)
>>> l1
[1, 2, 3, [11, 22, 33]]
>>> import copy
>>> l2 = copy.deepcopy(l1)
>>> l1[3][0]=55
>>> l1
[1, 2, 3, [55, 22, 33]]
>>> l2
[1, 2, 3, [11, 22, 33]]

列表解析/列表推导

列表解析:根据已有列表高效生成新列表的方式。因为列表解析生成新的列表,所以列表解析是编写在方括号中的。

列表解析表达式的语法:定义在中括号中,关键字for分割,for之前的是新列表的元素。

语法1:
[expression for var in iterable],例如list2=[i**2 for i in list1]

语法2:只有满足条件的元组才用于新列表的创建
[expression for var in iterable if cond_expr],例如list2=[i**2 for i in list1 if i>=3] 

语法3:循环嵌套,等同于2层for循环嵌套
[expression for var1 in iterable1 for var2 in iterable2],例如[(i,j) for i in list1 for j in list2]

如何理解列表解析?

list1=[i**2 for i in iter_obj if i>=3]
等同于
list1=[]
for i in iter_obj:
    if i>=3:
        list1.append(i**2)

列表使用细节

  1. 列表的元素并不真正存储数据,而是存放对象引用。

  2. 由于列表是可变对象,支持原处修改。所以可以使用索引赋值或分片赋值。Python中的索引赋值与C及大多数其他语言极为相似——Python用一个新值取代指定偏移的对象引用。

  3. 列表嵌套,可以构成矩阵(多维数组)。

>>> matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> matrix[0][0]
1
>>> matrix[1][1]
5
  1. 列表的sort、append等方法没有返回值,或者说返回值为None,所以list2=list1.append(55)时,list2的值为None。

  2. 列表作为可变对象,可以使用del语句在原处删除某个元素或某个分片。

del list1[0]
del list2[3:5]
  1. 因为分片赋值是删除+插入操作,也可以通过将空列表赋值给分片来删除列表片段(L[i:j]=[])。Python会删除左侧的分片,然后什么也不插入。另一方面,将空列表赋值给一个索引只会在指定的位置存储空列表的引用,而不是删除:
>>> list1
['glibc-2.13.4-2.41', 'glibc-2.3.4-2.41', 'glibc-2.5-24', 55]

>>> list1[0]=[]  #将空列表赋值给索引-->赋值
>>> list1
[[], 'glibc-2.3.4-2.41', 'glibc-2.5-24', 55]

>>> list1[:2]=[] #将空列表赋值给切片-->删除元素
>>> list1
['glibc-2.5-24', 55]
  1. 当赋值的值与分片重叠时,例如,L[2:5]=L[3:6]是可行的,这是因为要被插入的值会在左侧删除发生前被取出。

  2. 切片只能使用迭代对象来赋值,索引可以为任意对象

>>> l1=[1,2,3,4]
>>> l1[1:3]=4s
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only assign an iterable
>>> l1[1:3]=[4]
>>> l1[1]=4
>>> l1[1:3]=4
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only assign an iterable
>>> l1[1:3]='ni'
>>> l1[1:3]=4
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: can only assign an iterable

>>> l1[1:3]=[4]
>>> l1[1]=4
>>> l1[1:3]=4
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: can only assign an iterable
>>> l1[1:3]='ni'