Python 学习之列表


列表是可变的,即可修改其内容。

函数 list

如果你想使用字符串来创建列表,那就用函数list( 它实际上是一个类,而不是函数,但眼下,这种差别并不重要。),例如:

In [1]: a = list("hello")

In [2]: a
Out[2]: ['h', 'e', 'l', 'l', 'o']

要将字符列表(如前述代码第 3 行的 a)转换为字符串,可使用下面的表达式:
''.join(a)

In [3]: ''.join(a)
Out[3]: 'hello'

基本的列表操作

可对列表执行所有的标准序列操作,如索引、切片、拼接和相乘,但列表的有趣之处在于它是可以修改的。本节将介绍一些修改列表的方式:给元素赋值、删除元素、给切片赋值以及使用列表的方法。(请注意,并非所有列表方法都会修改列表。)

修改列表:给元素赋值

修改列表很容易,只需使用普通赋值语句即可——使用索引表示法给特定位置的元素赋值,如x[1] = 2

例如:

In [7]: x = [1,1,1]

In [8]: x[1] = 2

In [9]: x
Out[9]: [1, 2, 1]

注意:不能给不存在的元素赋值,因此如果列表的长度为2,你就不能写 “x[2]=…”

删除元素

从列表中删除元素也很容易,只需使用del语句即可。

In [11]: names = ['Alice', 'Beth', 'Cecil', 'Dee-Dee', 'Earl'] 

In [12]: del names[2]

In [13]: names
Out[13]: ['Alice', 'Beth', 'Dee-Dee', 'Earl']

注意到 Cecil 彻底消失了,而列表的长度也从5变成了4。

给切片赋值

切片是一项极其强大的功能,而能够给切片赋值让这项功能显得更加强大。

In [14]: name = list('Perl') 

In [15]: name
Out[15]: ['P', 'e', 'r', 'l']

In [16]: name[2:]=list('ar')

In [17]: name
Out[17]: ['P', 'e', 'a', 'r']

从上述代码可知,可同时给多个元素赋值。比较神奇的是,通过使用切片赋值,可将切片替换为长度与其不同的序列。

我们再看一个例子.

In [18]: name = list('Perl')

In [19]: name[1:]=list('ython')

In [20]: name
Out[20]: ['P', 'y', 't', 'h', 'o', 'n']

可以看到,把原本长度为3的切片换成了长度为5的切片。

使用切片赋值还可在不替换原有元素的情况下插入新元素。

In [21]: nums = [1,5]

In [22]: nums[1:1] = [2,3,4]

In [23]: nums
Out[23]: [1, 2, 3, 4, 5]

在这里,我们“替换”了一个空切片,相当于插入了一个序列。如果你要在位置 x 处插入一个序列,那么就可以用 somelist[x:x] = […]

你可采取相反的措施来删除切片。

In [23]: nums
Out[23]: [1, 2, 3, 4, 5]

In [24]: nums[1:4] = []

In [25]: nums
Out[25]: [1, 5]

上述代码与del numbers[1:4]等效。

In [26]: nums = [1,2,3,4,5]

In [27]: del nums[1:4]

In [28]: nums
Out[28]: [1, 5]

可以理解为删除切片 nums[1:4]

我们执行步长不为1(乃至为负)的切片赋值。

In [29]: nums = [1,2,3,4,5,6,7,8,9,10]

In [30]: nums[::2]=[0,0,0,0,0]

In [31]: nums
Out[31]: [0, 2, 0, 4, 0, 6, 0, 8, 0, 10]

In [31]: nums
Out[31]: [0, 2, 0, 4, 0, 6, 0, 8, 0, 10]

In [32]: nums[-1::-3]=[77,88,99]
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-32-be8451000971> in <module>()
----> 1 nums[-1::-3]=[77,88,99]

ValueError: attempt to assign sequence of size 3 to extended slice of size 4

为什么会出错呢?

因为 nums[-1::-3] 是一个长度为4的切片,而我们只提供了长度为3的序列 [77,88,99],这样是不行的。我们修改一下:

In [33]: nums[-1::-3]=[77,88,99,66]

In [34]: nums
Out[34]: [66, 2, 0, 99, 0, 6, 88, 8, 0, 77]

列表方法

方法是与对象联系紧密的函数。通常,像下面这样调用方法:
object.method(arguments)

方法调用与函数调用很像,只是在方法名前加上了对象和点号。列表包含多个可用来查看或修改其内容的方法。

append

方法 append 用于将一个对象附加到列表末尾。

In [35]: lst = [1,2,3]

In [36]: lst.append(4)

In [37]: lst
Out[37]: [1, 2, 3, 4]

注意,如果你忘了方法名字也没有关系,当输入完lst.后,按tab键,就可以联想出来所有的方法.

In [38]: lst.
lst.append   lst.copy     lst.extend   lst.insert   lst.remove   lst.sort     
lst.clear    lst.count    lst.index    lst.pop      lst.reverse  

你可能会问,为何给列表取lst这样糟糕的名字,而不称之为list呢?原因是 list 是一个内置函数( 实际上,从Python 2.2起,list就是类型,而不是函数了),如果将前述列表命名为list,就无法调用这个函数。

另外请注意,与其他几个类似的方法一样,append 就地修改列表。这意味着它不会返回修改后的新列表,而是直接修改旧列表。

clear

方法clear就地清空列表的内容。

In [40]: lst
Out[40]: [1, 2, 3]

In [41]: lst.clear()

In [42]: lst
Out[42]: []

这类似于切片赋值语句lst[:] = []

copy

方法 copy 复制列表。常规赋值只是将另一个名称关联到列表。

In [56]: a
Out[56]: [1, 2, 3]

In [57]: b = a

In [58]: b[1]=4

In [59]: a
Out[59]: [1, 4, 3]

In [60]: b
Out[60]: [1, 4, 3]

可以看到,当执行b = a的时候,其实是把 b 关联到列表 a,也就是说 b 和 a 是同一个列表;

In [51]: a = [1,2,3]

In [52]: b = a.copy()

In [53]: b[1]=4

In [54]: a
Out[54]: [1, 2, 3]

In [55]: b
Out[55]: [1, 4, 3]

可以看到,b 是独立于 a 的一个列表,修改 b 并不会修改 a;

所以,要让a和b指向不同的列表,就必须将b关联到a的副本(a.copy())。 这类似于使用list(a)或者a[:],他们也都复制 a

In [61]: a = [1,2,3]

In [62]: c = a[:]

In [63]: b = list(a)

In [64]: c[0] = 5

In [65]: b[0] = 7

In [66]: a
Out[66]: [1, 2, 3]

In [67]: b
Out[67]: [7, 2, 3]

In [68]: c
Out[68]: [5, 2, 3]

count

方法count计算指定的元素在列表中出现了多少次。

In [69]: lst = [1,2,3,3,4,5,3]

In [70]: lst.count(3)
Out[70]: 3

In [71]: lst.count(8)
Out[71]: 0

extend

方法extend让你能够同时将多个值附加到列表末尾,为此可将这些值组成的序列作为参数提供给方法extend。换言之,你可使用一个列表来扩展另一个列表。

In [72]: a = [1,2,3]

In [73]: b = [4,5,6]

In [74]: a.extend(b)

In [75]: a
Out[75]: [1, 2, 3, 4, 5, 6]

In [76]: b
Out[76]: [4, 5, 6]

这看起来类似于拼接,但存在一个重要差别,那就是将修改被扩展的序列(这里是a)。在常规拼接中,情况是返回一个全新的序列,并不会修改原来的序列。

In [77]: a = [1,2,3]

In [78]: b = [4,5,6]

In [79]: a + b
Out[79]: [1, 2, 3, 4, 5, 6]

In [80]: a
Out[80]: [1, 2, 3]

In [81]: b
Out[81]: [4, 5, 6]

如你所见,拼接出来的列表(第6行)与前一个示例扩展得到的列表(第8行)完全相同,但在这里a并没有被修
改。鉴于常规拼接必须使用a和b的副本创建一个新列表,因此如果你要获得exten的效果,可以这样写:

In [82]: a = a + b

In [83]: a
Out[83]: [1, 2, 3, 4, 5, 6]

虽然效果一样,但是效率低于 extend。

另外,拼接操作并非就地执行的,即它不会修改原来的列表。要获得与extend相同的效果,也可将列表赋给切片,如下所示:

In [84]: a = [1,2,3]

In [85]: b = [4,5,6]

In [86]: a[len(a):] = b

In [87]: a
Out[87]: [1, 2, 3, 4, 5, 6]

这虽然可行,但可读性不好。

index

方法index在列表中查找指定值第一次出现的索引。

In [89]: lst = [1,2,3,4,5,1,2]

In [90]: lst.index(1)
Out[90]: 0

In [91]: lst.index(6)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-91-1fe7e2916666> in <module>()
----> 1 lst.index(6)

ValueError: 6 is not in list

然而,搜索 6 时引发了异常,因为根本就没有找到这个数。

insert

方法insert用于将一个对象插入列表。

In [92]: nums = [1,2,3,5,6]

In [93]: nums.insert(3,'four')

In [94]: nums
Out[94]: [1, 2, 3, 'four', 5, 6]

参数中的3指定了要插入的索引位置。

也可使用给空切片赋值来获得与insert一样的效果。

In [98]: nums = [1,2,3,5,6]

In [99]: nums[3:3] = ['four']

In [100]: nums
Out[100]: [1, 2, 3, 'four', 5, 6]

这虽巧妙,但可读性根本无法与使用insert媲美。

注意,第3行不能写成nums[3:3] = 'four'

否则就成了:

In [95]: nums = [1,2,3,5,6]

In [96]: nums[3:3] = 'four'

In [97]: nums
Out[97]: [1, 2, 3, 'f', 'o', 'u', 'r', 5, 6]

pop

方法pop从列表中删除一个元素,并返回这一元素。

如果不指定参数,那么就删除最后一个元素;如果在参数中指定索引,那么就删除索引对应的元素。

In [101]: x = [1,2,3,4,5,6]

In [102]: x.pop()
Out[102]: 6

In [103]: x.pop()
Out[103]: 5

In [104]: x
Out[104]: [1, 2, 3, 4]

In [105]: x.pop(1)
Out[105]: 2

In [106]: x
Out[106]: [1, 3, 4]

注意:pop是唯一既修改列表又返回一个非None值的列表方法。

使用pop可实现一种常见的数据结构——栈(stack)。

push和pop是两种最基本的栈操作。Python没有提供push,但可使用append来替代。

remove

方法remove用于删除第一个为指定值的元素。

In [4]: x = [1,2,3,1,4,5]

In [5]: x.remove(1)

In [6]: x
Out[6]: [2, 3, 1, 4, 5]

请注意,remove是就地修改且不返回值的方法之一。不同于pop的是,它修改列表,但不返回任何值。

reverse

方法reverse按相反的顺序排列列表中的元素。

In [7]: x = [1,2,3,4,5]

In [8]: x.reverse()

In [9]: x
Out[9]: [5, 4, 3, 2, 1]

注意到reverse修改列表,但不返回任何值。

sort

方法sort用于对列表就地排序 。就地排序意味着对原来的列表进行修改,使其元素按顺序排列,而不是返回排序后的列表的副本。

In [10]: x = [2,3,9,1,4,5,5]

In [11]: x.sort()

In [12]: x
Out[12]: [1, 2, 3, 4, 5, 5, 9]

前面介绍了多个修改列表而不返回任何值的方法,在大多数情况下,这种行为都相当自然(例如,对append来说就如此)。需要强调sort的行为也是这样的,但是这种行为给很多人都带来了困惑。在需要排序后的列表副本并保留原始列表不变时,通常会遭遇这种困惑。为实现这种目标,一种直观(但错误)的方式是像下面这样做:

In [19]: x = [3,5,2,1,8]

In [20]: y = x.sort()

In [21]: print(y)
None

鉴于sort修改x且不返回任何值,最终的结果是x是经过排序的,而y包含None。为实现前述目标,正确的方式之一是先将y关联到x的副本,再对y进行排序,如下所示:

In [22]: x = [3,5,2,1,8]

In [23]: y = x.copy()

In [24]: y.sort()

In [25]: y
Out[25]: [1, 2, 3, 5, 8]

In [26]: x
Out[26]: [3, 5, 2, 1, 8]

为获取排序后的列表的副本,另一种方式是使用函数sorted。

In [27]: x = [3,5,2,1,8]

In [28]: y = sorted(x)

In [29]: y
Out[29]: [1, 2, 3, 5, 8]

In [30]: x
Out[30]: [3, 5, 2, 1, 8]

实际上,sorted 这个函数可用于任何序列,但总是返回一个列表 。

In [31]: sorted('BACW')
Out[31]: ['A', 'B', 'C', 'W']

参考资料

《Python基础教程(第三版)》,人民邮电出版社

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值