切片、迭代、生成器:Python4 有哪些高级功能?
切片:取指定索引范围的操作
L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack']
取前三个元素
>>> L[0:3]
['Michael', 'Sarah', 'Tracy']
#L[0:3]表示,从索引0开始取,直到索引3为止,但不包括索引3。即索引0,1,2,正好是3个元素
#如果是0也可以省略.即L[:3]
Python支持L[-1]取倒数第一个元素,那么它同样支持倒数切片
>>> L[-2:]
['Bob', 'Jack']
>>> L[-2:-1]
['Bob']
切片操作非常有用。首先,让我们创建一个 0-99 的范围:
>>> L = list(range(100))
>>> L
[0, 1, 2, 3, ..., 99]
您可以通过剪切轻松删除给定的数字范围。例如,前10位:
>>> L[:10]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
后十位
>>>L[-10:]
[90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
前11-20位:
>>>L[10:20]
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
前10位,每两位取一位:
>>>L[:10:2]
[0, 2, 4, 6, 8]
对于所有数字,每一位取一位五:
>>>L[::5]
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]
反向输出字符串
>>>str = 'abcd'
>>>str2 = str[::-1]
>>>print(str2)
dcba
tuple也是列表的一种,唯一的区别是tuple是不可变的。因此,tuple也可以使用切片操作,但是操作的结果仍然是tuple:
>>> (0, 1, 2, 3, 4, 5)[:3]
(0, 1, 2)
字符串'xxx'也可以看成是一个列表,每个元素是一个字符。因此,字符串也可以使用分段操作,但操作的结果仍然是一个字符串:
>>> 'ABCDEFG'[:3]
'ABC'
>>> 'ABCDEFG'[::2]
'ACEG'
###Iteration
如果给定了一个 list 或 tuple,我们可以通过 for 循环迭代该 list 或 tuple ,这种运动称为迭代。
在Python中,迭代是通过for...in进行的,这与Swift和OC中的for...in类似。
>>> d = {'a': 1, 'b': 2, 'c': 3}
>>> for key in d:
... print(key)
...
a
b
c
#因为dict的存储不是按照list的方式顺序排列,所以,迭代出的结果顺序很可能不一样。
默认情况下,听写会重复该键。如果要重复该值,可以在 d.values() 中使用 for value。如果想同时迭代key和value,可以在d.items()中使用for k, v。
for k, v in d.items():
print(k,v)
a ,1
b ,2
c ,3
由于字符串也是可迭代对象,所以它们也可以用在for循环中:
>>> for ch in 'ABC':
... print(ch)
...
A
B
C
所以如果我们使用for循环,只要作用于可迭代对象,for循环就可以正常工作,但是我们也不太关心对象是列表还是其他数据类型。判断是否是可迭代对象
>>> from collections import Iterable
>>> isinstance('abc', Iterable) # str是否可迭代
True
>>> isinstance([1,2,3], Iterable) # list是否可迭代
True
>>> isinstance(123, Iterable) # 整数是否可迭代
False
如果想在列表中实现类似Java的下标循环怎么办? Python 内置的 enumerate 函数可以将列表转换为索引元素对,这样索引和元素本身就可以在 for 循环中同时迭代:
>>> for i, value in enumerate(['A', 'B', 'C']):
... print(i, value)
...
0 A
1 B
2 C
###List Generation
List Generation 是列表推导式,这意味着 Python 有一个非常简单但功能强大的内置生成器,可用于创建列表。
要生成列表 [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]
要生成 [1x1, 2x2 , 3x3 , ..., 10x10]:
>>> [x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
仅过滤掉偶数方块:
>>> [x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]
列表生成也可以使用两个变量来生成列表
:
>>> d = {'x': 'A', 'y': 'B', 'z': 'C' }
>>> [k + '=' + v for k, v in d.items()]
['y=B', 'x=A', 'z=C']
L = ['Hello', ' World', 18, 'Apple', None] 将所有字符串由 L 转换为小写,输出结果为:['hello', 'world', 'apple']
>>>[x.lower() for x in L if isinstance(x,str)]
['hello', 'world', 'apple']
###Generator
带列表了解了,我们可以直接列一个清单。但由于内存限制,列表容量肯定是有限的。此外,创建一个包含100万个元素的列表不仅会占用大量的存储空间,而且如果我们只需要访问前几个元素,那么后续大部分元素所占用的空间都会被浪费。那么如果列表元素可以根据某种算法计算出来,那么我们是否可以在循环过程中不断计算后续元素呢?这样就无需创建完整列表,从而节省了大量空间。在Python中,这种同时重复和计算的机制称为生成器:生成器
。
1。创建生成器
:将列表生成表达式的[]更改为(),创建生成器
>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>
#创建L和g的区别仅在于最外层的[]和(),L是一个list,而g是一个generator。
生成器
。每次都会保存算法。调用next(g)
计算g
的下一个元素的值,直到计算完最后一个元素。如果没有更多元素,则滚动 StopIteration。 的错误。但是当我们创建了
。 生成器
之后,我们基本上就不再调用next()
,而是通过for
循环进行迭代,我们不用担心没什么好担心的。在停止迭代
二丶另一种定义生成器
的方式。如果函数定义中包含关键字yield
,则该函数不再是常规函数,而是生成器
#斐波拉契数列(Fibonacci)
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
return 'done'
生成器
,且函数的执行流程不同。函数按顺序执行,并在遇到 return 语句或最后一行函数语句时返回。每次调用 next()
时,都会执行成为 生成器
的函数。当遇到yield
语句时,从上次重新执行返回。 yield
在语句###Iterator
处继续执行,可以直接与for循环交互的数据类型如下: 一种是集合数据类型,如list、tuple、dict 、集合、str 等;一类是生成器,包括生成器和具有效率的生成器函数。
这些可以直接在for
循环中使用的对象统称为可迭代对象:Iterable
。您可以使用 isinstance()
来确定对象是否是 Iterable
对象:
>>> from collections import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance({}, Iterable)
True
>>> isinstance('abc', Iterable)
True
>>> isinstance((x for x in range(10)), Iterable)
True
>>> isinstance(100, Iterable)
False
和 生成器
无法单独作用于 为
循环,也可以通过函数next()
不断调用并返回下一个值,直到最后抛出StopIteration
错误,表示无法返回下一个值。可以被函数 next()
调用并连续返回下一个值的对象称为迭代器:Iterator
。您可以使用 isinstance()
来确定一个对象是否是 Iterator
对象:
>>> from collections import Iterator
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterator)
False
生成器都是 Iterator
对象,但是 列表
、 dict
、str
虽然是Iterable
,但不是Iterator
。将 list
、dict
、str
等Iterable
更改为 迭代器可以使用iter ( )
功能:
>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True
** 为什么list、dict、str等数据类型不是Iterator? ** 这是因为Python的Iterator
对象代表了一个数据流。 Iterator
对象可以通过函数next()
调用并不断返回后续数据。抛出错误 StopIteration
,直到没有更多数据为止。这个数据流可以被认为是一个有序的序列,但是我们无法提前知道序列的长度。我们只能通过函数next()
按需计算后面的数据,所以 Iterator
的计算是惰性的,只在需要返回后面数据时才计算。
迭代器
甚至可以表示无限的数据流,就像所有自然数一样。使用 list
永远不可能存储所有自然数。
作者:coderdrrting
链接:https://juejin.im/post/5a31d77b6fb9a044fd11c5fb
来源:掘金
版权归作者所有。商业转载请联系作者获得许可。非商业转载请注明出处。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。