Python/列表

维基教科书,自由的教学读本
跳到导航 跳到搜索

序列是Python中最基本的数据结构。序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推。

Python有6个内置的序列类型,但最常见的是列表和元组。

序列中元素的索引是基于0的。序列可以进行的操作有:索引,切片,加,乘,检查成员。内置确定序列的长度以及确定最大和最小的元素的方法。

列表是最常用的Python数据类型,它可以作为一个方括号内的逗号分隔值出现。列表的元素不需要具有相同的类型

创建一个列表,只要把逗号分隔的不同的数据项使用方括号括起来即可。以使用append()方法来添加列表项。使用 del 语句来删除列表的的元素。+ 号用于组合列表,* 号用于重复列表。


Python包含以下函数处理列表:

  • len(list) 列表元素个数
  • max(list) 返回列表元素最大值
  • min(list) 返回列表元素最小值
  • sum(list) 求和
  • list(seq) 将元组转换为列表

list的方法:

  • list.append(obj) 在列表末尾添加新的对象
  • list.count(obj) 统计某个元素在列表中出现的次数
  • list.extend(seq) 在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
  • list.index(obj) 从列表中找出某个值第一个匹配项的索引位置
  • list.insert(index, obj) 将对象插入列表
  • list.pop(obj=list[-1]) 移除列表中的一个元素(默认最后一个元素),并且返回该元素的值
  • list.remove(obj) 移除列表中某个值的第一个匹配项
  • list.reverse() 反向列表中元素
  • list.sort([func]) 对原列表进行排序


创建二维矩阵,可用下述简易方法,将需要的参数写入 cols 和 rows :

list_2d = [[0 for col in range(cols)] for row in range(rows)]

一般示例[编辑]

快速掌握列表:

list1 = []                      # A new empty list
list2 = [1, 2, 3, "cat"]        # A new non-empty list with mixed item types
list1.append("cat")             # Add a single member, at the end of the list
list1.extend(["dog", "mouse"])  # Add several members
list1.insert(0, "fly")          # Insert at the beginning
list1[0:0] = ["cow", "doe"]     # Add members at the beginning
doe = list1.pop(1)              # Remove item at index
if "cat" in list1:              # Membership test
  list1.remove("cat")           # Remove AKA delete
#list1.remove("elephant") - throws an error
for item in list1:              # Iteration AKA for each item
  print (item)
print("Item count:", len(list1)) # Length AKA size AKA item count
list3 = [6, 7, 8, 9]
for i in range(0, len(list3)):  # Read-write iteration AKA for each item
  list3[i] += 1                 # Item access AKA element access by index
last = list3[-1]                # Last item
nextToLast = list3[-2]          # Next-to-last item
isempty = len(list3) == 0       # Test for emptiness
set1 = set(["cat", "dog"])      # Initialize set from a list
list4 = list(set1)              # Get a list from a set
list5 = list4[:]                # A shallow list copy
list4equal5 = list4==list5      # True: same by value
list4refEqual5 = list4 is list5 # False: not same by reference
list6 = list4[:]
del list6[:]                    # Clear AKA empty AKA erase
list7 = [1, 2] + [2, 3, 4]      # Concatenation
print (list1, list2, list3, list4, list5, list6, list7)
print (list4equal5, list4refEqual5)
print (list3[1:3], list3[1:], list3[:2]) # Slices
print (max(list3 ), min(list3 ), sum(list3)) # Aggregates

print [x for x in range(10)]    # List comprehension
print [x for x in range(10) if x % 2 == 1]
print [x for x in range(10) if x % 2 == 1 if x < 5]
print [x + 1 for x in range(10) if x % 2 == 1]
print [x + y for x in '123' for y in 'abc']

创建List[编辑]

有两种方式创建List:赋值(静态),列表理解(list comprehensions) ("主动的").

简单创建[编辑]

在一对方括号中创建:

[ 1,2,3,"This is a list",'c',Donkey("kong") ]
  1. 列表元素可以是不同类型
  2. 对象可以'on the fly'创建并增加到列表中,最后一项是Donkey类实例

创建一个列表,其元素值不是字面量:

a = 2
b = 3
myList = [a+b, b+a, len(["a","b"])]

列表理解[编辑]

列表理解(list comprehension)描述了列表创建的过程。

例如,我们有一些单词:

listOfWords = ["this","is","a","list","of","words"]

取每个单词首字母创建一个列表:

>>> listOfWords = ["this","is","a","list","of","words"]
>>> items = [ word[0] for word in listOfWords ]
>>> print (items)
['t', 'i', 'a', 'l', 'o', 'w']

列表理解支持for语句多次出现:

>>> item = [x+y for x in 'cat' for y in 'pot']
>>> print (item)
['cp', 'co', 'ct', 'ap', 'ao', 'at', 'tp', 'to', 'tt']

列表理解支持if语句,只有满足特别条件的才能加入列表中:

>>> print [x+y for x in 'cat' for y in 'pot']
['cp', 'co', 'ct', 'ap', 'ao', 'at', 'tp', 'to', 'tt']
>>> print [x+y for x in 'cat' for y in 'pot' if x != 't' and y != 'o' ]
['cp', 'ct', 'ap', 'at']
>>> print [x+y for x in 'cat' for y in 'pot' if x != 't' or y != 'o' ]
['cp', 'co', 'ct', 'ap', 'ao', 'at', 'tp', 'tt']

Python 2.x中,列表理解不定义一个作用域。列表理解中绑定求值的变量再在求值完成后保持该绑定。Python 3.x中这些是局部变量:

>>> print x, y                         #Input to python version 2
t t                                    #Output using python 2

>>> print x, y                         #Input to python version 3
NameError: name 'x' is not defined     #Python 3 returns an error because x and y were not leaked

列表理解可以使用zip或itertools.izip处理多个列表:

[a - b for (a,b) in zip((1,2,3), (1,2,3))]  # will return [0, 0, 0]

列表快捷创建[编辑]

创建一个列表给定大小,每个元素被初始化:

>>> zeros=[0]*5
>>> print (zeros)
[0, 0, 0, 0, 0]

这种方式适用于任何数据类型:

>>> foos=['foo']*3
>>> print foos
['foo', 'foo', 'foo']

有一些警告:当用这种乘法形式建造列表时,Python使用每项的引用。这会造成修改其中一项带来所有项都改变的副作用。特别是多维数组:

listoflists=[ [0]*4 ] *5

这可以,但可能不是你所期望的:

>>> listoflists=[ [0]*4 ] *5
>>> print listoflists
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
>>> listoflists[0][2]=1
>>> print listoflists
[[0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0]]

Python使用内层列表的引用作为外层列表的元素。也可以用如下方式重演该问题:

>>> innerlist=[0]*4
>>> listoflists=[innerlist]*5
>>> print listoflists
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
>>> innerlist[2]=1
>>> print listoflists
[[0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0]]

可以用列表理解来避免上述副作用:

>>> listoflists=[[0]*4 for i in range(5)]
>>> print listoflists
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
>>> listoflists[0][2]=1
>>> print listoflists
[[0, 0, 1, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

列表的尺寸[编辑]

使用内建的len()函数:

>>> len([1,2,3])
3
>>> a = [1,2,3,4]
>>> len( a )
4

组合多个列表[编辑]

只需要把它们加起来:

>>> [1,2] + [3,4]
[1, 2, 3, 4]

另一种方法是使用列表的成员函数extend. 如果在lambda表达式内部组合多个列表, extend是正确的方法。

>>> a = [1,2,3]
>>> b = [4,5,6]
>>> a.extend(b)
>>> print a
[1, 2, 3, 4, 5, 6]

列表追加一个元素,用列表的成员函数append

>>> p=[1,2]
>>> p.append([3,4])
>>> p
[1, 2, [3, 4]]
>>> # or
>>> print p
[1, 2, [3, 4]]

列表的切片[编辑]

连续切片[编辑]

类似于strings,列表可以被索引、切片:

>>> list = [2, 4, "usurp", 9.0, "n"]
>>> list[2]
'usurp'
>>> list[3:]
[9.0, 'n']

不同于字符串,对列表的切片可以赋新值:

>>> list[1] = 17
>>> list
[2, 17, 'usurp', 9.0, 'n']

甚至可以给列表的切片赋以具有不等长度的新值:

>>> list[1:4] = ["opportunistic", "elk"]
>>> list
[2, 'opportunistic', 'elk', 'n']

可以在列表的开头插入新的值序列:

>>> list[:0] = [3.14, 2.71]
>>> list
[3.14, 2.71, 2, 'opportunistic', 'elk', 'n']

类似的,也可以在列表末尾追加新的值序列:

>>> list[len(list):] = ['four', 'score']
>>> list
[3.14, 2.71, 2, 'opportunistic', 'elk', 'n', 'four', 'score']

可以彻底改编列表内容:

>>> list[:] = ['new', 'list', 'contents']
>>> list
['new', 'list', 'contents']

列表赋值语句的右端可以是任何可迭代类型:

>>> list[:2] = ('element',('t',),[])
>>> list
['element', ('t',), [], 'contents']

切片创造了列表的新的拷贝:

>>> original = [1, 'element', []]
>>> list_copy = original[:]
>>> list_copy
[1, 'element', []]
>>> list_copy.append('new element')
>>> list_copy
[1, 'element', [], 'new element']
>>> original
[1, 'element', []]

注意:这是浅拷贝,是与最初列表相同的引用,对易变类型要格外小心:

>>> list_copy[2].append('something')
>>> original
[1, 'element', ['something']]

不连续切片[编辑]

使用运算符 lower_limit:upper_limit:step可以做不连续切片:

>>> list = [i for i in range(10) ]
>>> list
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list[::2]
[0, 2, 4, 6, 8]
>>> list[1:7:2]
[1, 3, 5]

比较列表[编辑]

列表可以做相等比较:

>>> [1,2] == [1,2]
True
>>> [1,2] == [3,4]
False

列表也可以用小于运算符做词典序比较:

>>> [1,2] < [2,1]
True
>>> [2,2] < [2,1]
False
>>> ["a","b"] < ["b","a"]
True

排序列表[编辑]

概览:

list1 = [2, 3, 1, 'a', 'B']
list1.sort()                                   # list1 gets modified, case sensitive
list2 = sorted(list1)                          # list1 is unmodified; since Python 2.4
list3 = sorted(list1, key=lambda x: x.lower()) # case insensitive ; will give error as not all elements of list are strings and .lower() is not applicable
list4 = sorted(list1, reverse=True)            # Reverse sorting order: descending
print list1, list2, list3, list4

列表的成员函数sort做原地排序,返回值为None:

>>> list1 = [2, 3, 1, 'a', 'b']
>>> list1.sort()
>>> list1
[1, 2, 3, 'a', 'b']

Python 2.4及以上版本提供一些参数:

  • sort(cmp,key,reverse)
    • cmp : 指定一个定制的比较函数,这个函数接收两个参数(元素),如果第一个参数小于第二个参数,返回一个负数;如果第一个参数等于第二个参数,返回零;如果第一个参数大于第二个参数,返回一个正数。默认值为None。
    • key : 这是一个函数,传入key值,列表根据该函数返回值做排序。
    • reverse : sort(reverse=True)或sort(reverse=False)

Python内置函数sorted()不是原地排序,而是返回一个有序的列表:

>>> list1 = [5, 2, 3, 'q', 'p']
>>> sorted(list1)
[2, 3, 5, 'p', 'q']
>>> list1
[5, 2, 3, 'q', 'p']

链接:

迭代[编辑]

列表上的迭代:

列表上的只读迭代,即遍历列表的每个元素:

list1 = [1, 2, 3, 4]
for item in list1:
  print item

列表上的可写迭代:

list1 = [1, 2, 3, 4]
for i in range(0, len(list1)):
  list1[i]+=1 # Modify the item at an index as you see fit
print list

列表上迭代,步长不为1:

for i in range(1, 13+1, 3): # For i=1 to 13 step 3
  print i
for i in range(10, 5-1, -1): # For i=10 to 5 step -1
  print i

满足特定条件(过滤)的迭代:

for item in list:
  if not condition(item):
    continue
  print item

参见 Python/Loops#For_Loops.

删除[编辑]

在给定索引位置删除元素 (参见#pop(i)):

list1 = [1, 2, 3, 4]
list1.pop() # Remove the last item
list1.pop(0) # Remove the first item , which is the item at index 0
print list1

list1 = [1, 2, 3, 4]
del list1[1] # Remove the 2nd element; an alternative to list.pop(1)
print list1

按值删除元素:

list1 = ["a", "a", "b"]
list1.remove("a") # Removes only the 1st occurrence of "a"
print list1

保留满足条件的元素,删除不满足条件的元素:

list1 = [1, 2, 3, 4]
newlist = [item for item in list1 if item > 2]
print newlist

使用"[:]":

list1 = [1, 2, 3, 4]
sameList = list1
list1[:] = [item for item in list1 if item > 2]
print sameList, sameList is list1

把条件作为独立的函数:

list1 = [1, 2, 3, 4]
def keepingCondition(item):
  return item > 2
sameList = list1
list1[:] = [item for item in list1 if keepingCondition(item)]
print sameList, sameList is list1

迭代列表同时做删除要特别小心索引的使用:

list1 = [1, 2, 3, 4]
index = len(list1)
while index > 0:
  index -= 1
  if not list1[index] < 2:
    list1.pop(index)

链接:

聚合[编辑]

有3个内建的算术聚合函数:minimum, maximum, sum:

list = [1, 2, 3, 4]
print max(list), min(list), sum(list)
average = sum(list) / float(len(list)) # Provided the list is non-empty
# The float above ensures the division is a float one rather than integer one.
print average
list = ["aa", "ab"]
print max(list), min(list) # Prints "ab aa"

复制[编辑]

浅复制:

list1= [1, 'element']
list2 = list1[:] # Copy using "[:]"
list2[0] = 2 # Only affects list2, not list1
print list1[0] # Displays 1

#对比
list1 = [1, 'element']
list2 = list1
list2[0] = 2 # Modifies the original list
print list1[0] # Displays 2

下例可以说明浅拷贝:

list1 = [1, [2, 3]] # Notice the second item being a nested list
list2 = list1[:] # A shallow copy
list2[1][0] = 4 # Modifies the 2nd item of list1 as well
print list1[1][0] # Displays 4 rather than 2

深拷贝例子:

import copy
list1 = [1, [2, 3]] # Notice the second item being a nested list
list2 = copy.deepcopy(list1) # A deep copy
list2[1][0] = 4 # Leaves the 2nd item of list1 unmodified
print list1[1][0] # Displays 2

链接:

清空[编辑]

清空一个列表:

del list1[:] # Clear a list
list1 = []   # Not really clear but rather assign to a new empty list

注意不同清空方式对列表作为函数参数的影响:

def workingClear(ilist):
  del ilist[:]
def brokenClear(ilist):
  ilist = [] # Lets ilist point to a new list, losing the reference to the argument list
list1=[1, 2]; workingClear(list1); print (list1)
list1=[1, 2]; brokenClear(list1); print (list1)

删除冗余元素[编辑]

Removing duplicate items from a list (keeping only unique items) can be achieved as follows.

如果列表元素是可哈希的,使用列表理解很快:

list1 = [1, 4, 4, 5, 3, 2, 3, 2, 1]
seen = {}
list1[:] = [seen.setdefault(e, e) for e in list1 if e not in seen]

如果列表元素是可哈希的,使用索引迭代会慢一些:

list1 = [1, 4, 4, 5, 3, 2, 3, 2, 1]
seen = set()
for i in range(len(list1) - 1, -1, -1):
  if list1[i] in seen:
    list1.pop(i)
  seen.add(list1[i])

如果某些元素是不可哈希的,可以把所有访问过的元素放在一个列表中:

list1 = [1, 4, 4, ["a", "b"], 5, ["a", "b"], 3, 2, 3, 2, 1]
seen = []
for i in range(len(list1) - 1, -1, -1):
  if list1[i] in seen:
    list1.pop(i)
  seen.append(list1[i])

如果每个元素是可哈希的且保持元素的序无关紧要:

list1 = [1, 4, 4, 5, 3, 2, 3, 2, 1]
list1[:] = list(set(list1))  # Modify list1
list2 = list(set(list1))

链接:

列表的成员函数[编辑]

append(x)[编辑]

在列表尾部追加:

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

pop(i)[编辑]

删除索引位置的元素。缺省删除尾部元素

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

运算符[编辑]

+[编辑]

连接两个列表。

*[编辑]

把一个列表复制多次连接起来。

in[编辑]

运算符'in'有两种用途:在for循环中遍历每个元素;或者对一个值是否出现在列表种给出判断结果True或False

>>> list = [1, 2, 3, 4]
>>> if 3 in list:
>>>    ....
>>> l = [0, 1, 2, 3, 4]
>>> 3 in l
True
>>> 18 in l
False
>>>for x in l:
>>>    print x
0
1
2
3
4

差集[编辑]

两个列表的差集,需要迭代:

a = [0, 1, 2, 3, 4, 4]
b = [1, 2, 3, 4, 4, 5]
print ([item for item in a if item not in b])
# [0]

交集[编辑]

两个列表的交集,减去差集:

a = [0, 1, 2, 3, 4, 4]
b = [1, 2, 3, 4, 4, 5]
dif = [item for item in a if item not in b]
print [item for item in a if item not in dif]
# [1, 2, 3, 4, 4]

练习[编辑]

  1. Use a list comprehension to construct the list ['ab', 'ac', 'ad', 'bb', 'bc', 'bd'].
  2. Use a slice on the above list to construct the list ['ab', 'ad', 'bc'].
  3. Use a list comprehension to construct the list ['1a', '2a', '3a', '4a'].
  4. Simultaneously remove the element '2a' from the above list and print it.
  5. Copy the above list and add '2a' back into the list such that the original is still missing it.
  6. Use a list comprehension to construct the list ['abe', 'abf', 'ace', 'acf', 'ade', 'adf', 'bbe', 'bbf', 'bce', 'bcf', 'bde', 'bdf']

外部链接[编辑]