Python编程核心内容之二——切片、迭代和列表生成式
Python版本:3.6.2 操作系统:Windows 作者:SmallWZQ
最近太忙啦。很多事情需要自己处理,感觉时间不够用啊~~~~今后,博客更新时间可能会慢下来(但不能荒废了学习,要学习就得进行总结,哪怕借鉴前辈的学习资料),因此,无论闲忙,总是要学会总结。哈哈,正所谓“人不为己,天诛地灭”嘛。嘿嘿,没这么回事,说笑的……好像又扯远了。OK,回归正题,下面将回到Python先~~~
Python编程中,你如果要编写出很多有用的程序,必须掌握数据类型、语句和函数。对于Python编程,原则有二:一是代码不是越多越好,而是越少越好;二是代码不是越复杂越好,而是越简单越好。你还想“一行代码两块钱”。效率决定一切。
下面来个例子(不然,全是文字,会晕~~~)【实现1,3,5,7,9,……99的列表】:
1 #赚钱版代码 2 >>>n = 1 3 >>>L = [] 4 >>>while n <= 99: 5 ... L.append(n) 6 ... n = n + 2 7 ... 8 >>>print(L) #好多money,但老板不一定会给噢 9 #略缩版代码 10 >>>L= list(range(1,100,2)) 11 >>>print(L) 12 #终极版代码 13 >>>[x for x in range(1,100,2)]
其实,上述代码涉及到的代码主要包括循环、range()、分片、列表生成式。通过例子,我们知道:Python提供了很多有用的高级特性,灵活运用这些特性,可以减少我们很多代码量,提高效率。
切片
切片是Python编程的高级特性之一。切片可以访问一定范围内的元素,通过冒号(:)【该冒号是英文版的】隔开两个索引实现。
关于Python编程中的符号(比如冒号,逗号,括号……)都是英文版的【重要的事情说好多遍,因为自己平时编程也会时常出现这类错误】,否则程序编译会有Error,而且这种类型的错误还不好发现。因此,细节决定高度~~~
1 #切片的魔力 2 >>>L = [1,2,3,4,5,6,7,8,9,10] 3 >>>L[2:5] 4 3,4,5 5 >>>L[0:1] 6 1
切片操作的实现需要提供两个索引作为边界,第一个索引的元素是包含在切片内的,而第二个则不包含在切片内。
注:如果第一个索引是0,可以省略:
1 >>>L = [1,2,3,4,5,6,7,8,9,10] 2 >>>L[0:3] 3 1,2,3 4 >>>L[:3] 5 1,2,3
既然Python支持L[-1]取倒数第一个元素,那么它同样支持倒数切片:
1 >>>L = [1,2,3,4,5,6,7,8,9,10] 2 >>>L[-2:] 3 9,10 4 >>>L[-2,-1] 5 9
Python 3.x版本中,切片操作还支持步长:
1 >>>L = [1,2,3,4,5,6,7,8,9,10] 2 >>>L[::1] 3 [1,2,3,4,5,6,7,8,9,10] 4 >>>L[0:10:2] 5 [1,3,5,7,9] 6 >>>L[1:10:5] 7 [2,7]
tuple也是一种list,唯一区别是tuple不可变。因此,tuple也可以用切片操作,只是操作的结果仍是tuple:
1 >>> (0, 1, 2, 3, 4, 5)[:3] 2 (0, 1, 2)
字符串’xxx’也可以看成是一种list,每个元素就是一个字符。因此,字符串也可以用切片操作,只是操作结果仍是字符串:
1 >>> 'ABCDEFG'[:3] 2 'ABC' 3 >>> 'ABCDEFG'[::2] 4 'ACEG'
Python没有针对字符串的截取函数,只需要切片一个操作就可以完成,非常简单。
Python的切片非常灵活,一行代码就可以实现很多行循环才能完成的操作。
迭代
Iteration是Python编程中最重要的高级特性。迭代(Iteration):给定一个list或tuple,通过for
循环来遍历这个list或tuple。故而,Python是通过for...in循环实现迭代的。
list这种数据类型虽然有下标,但很多其他数据类型是没有下标的,但是,只要是可迭代对象,无论有无下标,都可以迭代,比如dict就可以迭代:
1 >>> d = {'A': 1, 'B': 2, 'C': 3} 2 >>> for key in d: 3 ... print(key) 4 ... 5 A 6 B 7 C 8 >>>
因为dict的存储不是按照list的方式顺序排列,所以,迭代出的结果顺序很可能不一样。
默认情况下,dict迭代的是key。如果要迭代value,可以用for value in d.values()
,如果要同时迭代key和value,可以用for k, v in d.items()
。
由于字符串也是可迭代对象,因此,也可以作用于for
循环:
1 >>> for ch in 'ABC': 2 ... print(ch) 3 ... 4 A 5 B 6 C
因此,当我们使用for
循环时,只要作用于一个可迭代对象,for
循环就可以正常运行,而我们不太关心该对象究竟是list还是其他数据类型。
那么,如何判断一个对象是可迭代对象呢?方法是通过collections模块的Iterable类型判断:
1 >>> from collections import Iterable 2 >>> isinstance('abc', Iterable) # str是否可迭代 3 True 4 >>> isinstance([1,2,3], Iterable) # list是否可迭代 5 True 6 >>> isinstance(123, Iterable) # 整数是否可迭代 7 False
在for循环里,同时引用了两个变量,在Python里是很常见的,比如下面的代码:
1 >>> for x, y in [(1, 1), (2, 4), (3, 9)]: 2 ... print(x, y) 3 ... 4 1 1 5 2 4 6 3 9
任何可迭代对象都可以作用于for
循环,包括我们自定义的数据类型,只要符合迭代条件,就可以使用for
循环。
列表生成式
列表生成式作为Python编程的高级特性,可以简化不少代码量。列表生成式(List Comprehensions)是Python内置的非常简单却强大的可以用来创建list的生成式。
举个例子,要生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]可以用list(range(1, 11)):
1 >>> list(range(1, 11)) 2 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
但如果要生成[1x1, 2x2, 3x3, …, 10x10]怎么做?方法一是循环:
1 >>> L = [] 2 >>> for x in range(1, 11): 3 ... L.append(x * x) 4 ... 5 >>> L 6 [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
但是循环太繁琐,而列表生成式则可以用一行语句代替循环生成上面的list:
1 >>> [x * x for x in range(1, 11)] 2 [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
写列表生成式时,把要生成的元素x * x放到前面,后面跟for循环,就可以把list创建出来,for循环后面还可以加上if判断,这样我们就可以筛选出仅偶数的平方:
1 >>> [x * x for x in range(1, 11) if x % 2 == 0] 2 [4, 16, 36, 64, 100]
列表生成式也可以使用两个变量来生成list:
1 >>> d = {'x': 'A', 'y': 'B', 'z': 'C' } 2 >>> [k + '=' + v for k, v in d.items()] 3 ['y=B', 'x=A', 'z=C']
把一个list中所有的字符串变成小写:
1 >>> L = ['Hello', 'World', 'IBM', 'Apple'] 2 >>> [s.lower() for s in L] 3 ['hello', 'world', 'ibm', 'apple']
列表生成式不是真正的语句,而是看起来像循环的表达式,这是将它归为循环语句的原因。该功能很强大,但大多数情况下,直接使用循环和条件语句也能完成。然而,列表生成式的程序十分简洁,更加易读。
下面来个例子:
1 L1 = ['Hello', 'World', 18, 'Apple', None] 2 L2= [s.lower() for s in L1 if isinstance(s,str)]