天天看点

Python 语言学习要点记录5- list 相关

作者:逸剑听潮

list

list 常用的内置函数:

list.append(x),将项目添加到列表的末尾。 等价于 a[len(a):] = [x]。

list.extend(可迭代),过附加 iterable 中的所有项目来扩展列表。 等价于 a[len(a):] = 可迭代。

list.insert(i, x),在给定位置插入一个项目。 第一个参数是要插入的元素的索引,因此 a.insert(0, x) 在列表的前面插入,而 a.insert(len(a), x) 等同于 a.append( x)。

list.remove(x),从列表中删除第一个值等于 x 的项。 如果找不到该项,它会引发 ValueError。

list.pop([i]),删除列表中给定位置的项目,并将其返回。 如果未指定索引,a.pop() 将删除并返回列表中的最后一项。

list.clear(),从列表中删除所有项目。 等价于del a[:]。

list.index(x[, start[, end]]),返回列表中第一项的值等于 x 的从零开始的索引。 如果没有这样的项目,则引发 ValueError。可选参数 start 和 end 被解释为切片符号,并用于将搜索限制到列表的特定子序列。 返回的索引是相对于完整序列的开头而不是起始参数计算的。

list.count(x),返回 x 在列表中出现的次数。

list.sort(*, key=None, reverse=False),对列表项进行排序。

list.reverse(),反转列表的元素。

list.copy(),返回列表的浅表副本。 等价于[:]。

fruits = ['orange', 'apple', 'pear', 'banana', 'kiwi', 'apple', 'banana']
fruits.count('apple')  #2
fruits.count('tangerine')  #0
fruits.index('banana')  #3
fruits.index('banana', 4)  #  6
fruits.reverse()  
fruits    #['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange']
fruits.append('grape')
fruits   #['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange', 'grape']
fruits.sort()
fruits  #['apple', 'apple', 'banana', 'banana', 'grape', 'kiwi', 'orange', 'pear']
fruits.pop()  #'pear'           

仅修改列表的insert、remove或sort等方法没有打印出返回值,其实它们返回的是默认值 None。 在 Python 中所有可变数据结构都遵循的设计原则。

如果 list 中的数据不是相同类型时,是没办法比较和排序的,例如 [5, 'abc', True],数字类型和字符串进行比较。而且有些数据类型没有定义排序功能,例如复数,2 + 7j 和 3+5j 是不能进行比较的。

把 list 当作堆栈

列表提供的函数,可以很容易将列表用作堆栈,其中最后添加的元素,也是第一个可以弹出到的元素(“后进先出”)。可以使用 append()将数据项添加到堆栈顶。 使用不带显式索引的 pop()从堆栈顶部弹出数据。

stack = [11,22,33,44]
stack.append(55)
stack.append(66)  #压栈
stack   #[11,22,33,44,55,66]
stack.pop() #66 弹栈
stack   #[11,22,33,44,55]
stack.pop() #55 弹栈
stack   #[11,22,33,44]           

把 list 当作队列

也同样可以将 list 用作队列,第一个添加进去的元素,先被弹出("先进先出"),然后 list 作为队列的执行效率不是太高。虽然从列表末尾追加和弹出数据很快,但从列表开头插入或弹出却很慢(因为所有其他元素都必须移动一个)。

要实现队列,使用 collections.deque,它可以实现从两端进行快速添加和弹出。 例如:

from collections import deque
queue = deque(["apple", "orange", "banana"])
queue.append("Pear")    #压栈
queue.append("peach")   #压栈
queue.popleft()    #apple   左侧弹栈
queue.popleft()     #orange   左侧弹栈
queue      #deque(['banana', 'Pear', 'peach'])
queue.pop()   #peach   右侧弹栈
queue      #deque(['banana', 'Pear'])           

list 推导式

列表推导式提供了一种创建 list 的简洁方法。常见的应用场景是创建新列表,其中每个元素都是应用于另一个序列或可迭代对象的每个成员的某些操作的结果,或者创建满足特定条件的那些元素的子序列。例如创建包含整数平方的 list:

squares = []
for x in range(10):
    squares.append(x**2)
    
squares   #[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
x #9           

变量 x 不断的被新值覆盖,但是它在循环之后依然存在。可以使用以下方法计算没有任何副作用的正方形列表:

squares = list(map(lambda x: x**2, range(10)))           

或者,更简洁易懂的方式

squares = [x**2 for x in range(10)]           

list 推导式由括号组成,内部包含表达式,后面跟着 for 子句,然后是零个或多个 for 或 if 子句。 结果将是一个新列表,该列表是在其后的 for 和 if 子句的上下文中计算表达式而产生的。 例如,下面的 list 组合了两个 list 的元素(两个 list 中互不相同的元素):

data = [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]  
data #[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]           

注意当创建的 list 的元素是 tuple 类型是,推导式中的 tuple 数据必须放在()中,否则会报错。

等同于下面的实现:

combs = []
for x in [1,2,3]:
    for y in [3,1,4]:
        if x != y:
            combs.append((x, y))

combs   #[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]           

更多例子:

list1 = [-3,-2,-1,0,1,2,3]
[x*2 for x in list1]   #[-6, -4, -2, 0, 2, 4, 6]
[x for x in list1 if x >= 0]   #[0, 1, 2, 3]
[abs(x) for x in vec]   #[3, 2, 1, 0, 1, 2, 3]

fruit = ["     apple", "orange     ", "     banana     "]
[f.strip() for f in fruit]   #['apple', 'orange', 'banana']
#生成包含元组tuple类型的元素,必须将数据放在()中,否则会报错
[(x, x**2) for x in range(6)]   #[(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)]

list2 = [[1,2,3], [4,5,6], [7,8,9]]
[n for elem in list2 for n in elem]   #[1, 2, 3, 4, 5, 6, 7, 8, 9]           

list 推导式可以包含更复杂的表达式和嵌套函数:

from math import pi
[str(round(pi, i)) for i in range(1, 6)]   #['3.1', '3.14', '3.142', '3.1416', '3.14159']           

列表推导式嵌套

列表推导式中的初始表达式可以是任意表达式,可以包括另一个列表推导式。

# 定义3x4的数字矩阵
matrix = [
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12],
]
# 实现行列转换
[[row[i] for row in matrix] for i in range(4)]  #[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]           

等同于:

trans = []
for i in range(4):
    trans.append([row[i] for row in matrix])

trans  #[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]           

还等同于:

trans = []
for i in range(4):
   trans_row = []
    for row in matrix:
        trans_row.append(row[i])
    trans.append(trans_row)

trans  #[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]           

在真正编程时,我们更倾向于使用内置函数而不是复杂的流程语句。 zip() 函数就可以很容易的实现上面的功能:

list(zip(*matrix))   #[(1, 5, 9), (2, 6, 10), (3, 7, 11), (4, 8, 12)]           

del 语句

del 可以通过索引删除单个元素,也可以通过切片删除多个元素,或者整个 list。del 和 pop()的不同在于前者没有返回值,后者有返回值。

data = [1, 2, 3, 4, 5, 6, 7, 8]
del data[0]
data #[2, 3, 4, 5, 6, 7, 8]
del data[1:3]   #[2, 5, 6, 7, 8]
del data[:]
data  #[]
del data  #删除整个 data