一、切片
取一个list或tuple的部分元素是非常常见的操作。比如一个list如下:
>>> L = ['a', 'b', 'c', 'd', 'e']
取前三个元素,该怎么做?
笨方法:用循环实现
r = []
n = 3
for i in range(n):
r.append(L[i])
用此方法十分繁琐,因此,Python提供了切片(Slice)操作符,大大简化 这种操作。
方括号中包含有三个参数L[a:b:c]
,其中a表示从第a个索引开始,b表示到第b个索引结束,但不包含b,c表示步长。
>>> L[0:3]
['a', 'b', 'c']
L[0:3]
表示,从索引0
开始,直到3
为止,但不包含3
。即0
, 1
, 2
三个元素
如果第一个索引是0
,还可以省略:
>>> L[:3]
['a', 'b', 'c']
同样索引值也可以是负的,表示倒数切片
>>> L[-2:]
['d', 'e']
>>> L[-2:-1]
['d']
记住:倒数第一个元素的索引是-1
而不是0
。
括号内甚至可以什么都不写,只写[:]
这样就可以原样复制一个list:
>>> L[:]
['a', 'b', 'c', 'd', 'e']
tuple也是一种list,唯一的区别就是tuple不可变。因此,tuple也可以用切片操作,只是操作的结果仍是tuple:
>>> (0, 1, 2, 3, 4, 5)[:3]
(0, 1, 2)
类似的字符串也可以看成是一种list,每个元素就是一个字符
>>> 'abcdefg'[:3]
'abc'
>>> 'abcdefg'[::2]
'aceg'
二、迭代
如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种便利我们称为迭代(Iteration)。
在Python中,迭代是通过for ... in
来完成的,而很多语言比如C语言,迭代list是通过下表完成的,比如Java代码:
for(i=0; i<list.length; i++){
n = list[i];
}
可以看出,Python的for
循环抽象程度要高于Java的for
循环,因为Python的for
循环不仅可以用在list或tuple上,还可以作用在其他可第二代对象上。
list这种数据类型虽然有下标,但很多其他数据类型是没有下标的,但是,只要是可迭代对象,无论有无下标,都可以迭代,比如dict就可以:
>>> d = {'a' : 1, 'b' : 2, 'c' : 3}
>>> for key in d:
. . . print(key)
. . .
a
c
b
因为dict的存储不是按照list的方式顺序排列,所以,迭代出的结果顺序很可能不一样。
默认情况下, dict迭代的是key。如果要迭代value,可以用for value in d.values()
,涂过要同时迭代key和value,可以用for k, v in d.items()
。
由于字符串也是可迭代对象,因此也可以作用于for循环:
>>> for ch in 'abc':
. . . print(ch)
. . .
a
b
c
所以当我们使用for
循环时,只要作用于一个可迭代对象,for
循环就可以正常运行, 而我们不太关心该对象是list还是其他数据类型。
如何判断一个对象是可迭代对象呢?通过collections模块中的Iterable类型判断:
>>> from collections import Iterable
>>> isinstance('abc', Iterable)
True
>>> isinstance([1, 2, 3], Iterable)
True
>>> isinstance(123, Iterable)
False
最后一个小问题,如果要对list实现Java那样的下标循环怎么办?Python中内置的enumerate
函数可以把一个list变成 索引-元素对,这样就可以在循环中同时迭代索引和元素本身:
>>> for i, value in enumerate(['a', 'b', 'c']):
. . . print(i, value)
. . .
0 a
1 b
2 c
三、列表生成式
列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。
比如,要生成list[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
可以用list(range(1, 11))
:
>>> list(range(1, 11))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
但是如果要生成[11, 22, 33, 44, ... , 10*10]呢?方法一是循环:
>>> L = []
>>> for x in range(1, 11):
. . . L.append(x * x)
. . .
>>> L
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
但是太繁琐了,而列表生成式则可以用一行语句代替循环生成上面的list:
>>> [x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
写列表生成式时,把要生成的元素放在前米娜,后面跟上for
循环, 就可以把list创建出来。
还可以使用两层循环,可以生成全排列:
>>> [m + n for m in 'ABC' for n in 'abc']
['Aa', 'Ab', 'Ac', 'Ba', 'Bb', 'Bc', 'Ca', 'Cb', 'Cc']
但是三层和三层以上的循环就很少用到了。
网友评论