What does the “yield” keyword do?

微信公众号:stackflow
若有问题或建议,请公众号留言
Question:https://stackoverflow.com/questions/1132941/
最近更新:2018-12-17node

需求分析

英文yield,意为屈从、量产、投资收益。而python中则是一个表达式,面试中常常会被问到。那yield是用来干吗的呢?首先咱们要了解的是:iterable(迭代)、generator(生成器),而后才是yield(生成可迭代对象)python

 1def _get_child_candidates(self, distance, min_dist, max_dist):
2    if self._leftchild and distance - max_dist < self._median:
3        yield self._leftchild
4    if self._rightchild and distance + max_dist >= self._median:
5        yield self._rightchild
6
7# the caller
8result, candidates = [], [self]
9while candidates:
10    node = candidates.pop()
11    distance = node._get_dist(obj)
12    if distance <= max_dist and distance >= min_dist:
13        result.extend(node._values)
14    candidates.extend(node._get_child_candidates(distance, min_dist, max_dist))
15return result
复制代码

Answers

Iterables

全部可用for…in…来遍历的对象都是可迭代的,如lists, strings, files…面试

1>>> mylist = [x*x for x in range(3)]
2>>> for i in mylist:
3...    print(i)
40
51
64
复制代码

Generators

生成器都是可迭代的,只是只能迭代一次。由于生成器不存储全部值到内存中,而是动态的生成值。 微信

 1mygenerator = (x*x for x in range(3))
2for i in mygenerator:
3    print(i)
4
5print(mygenerator)
6for i in mygenerator: # 无输出
7    print(i)
8
9# the result:
100
111
124
13<generator object <genexpr> at 0x000002AB4F68B258>
复制代码

yield

用法同return,只是函数返回一个可迭代的生成器app

 1>>> def createGenerator():
2...    mylist = range(3)
3...    for i in mylist:
4...        yield i*i
5...
6>>> mygenerator = createGenerator() # create a generator
7>>> print(mygenerator) # mygenerator is an object!
8<generator object createGenerator at 0xb7555c34>
9>>> for i in mygenerator:
10...     print(i)
110
121
134
复制代码

以上只是基础,问题中的代码执行过程更复杂,分析以下:
一、while循环遍历列表,每次被迭代时,列表会扩展
二、extend方法是追加值到列表中
Python指望迭代,所以它能够处理字符串、列表、元组和生成器!这就是Python如此cool的缘由之一。函数

下面尝试一下生成器的高级用法:post

Controlling a generator exhaustion

 1>>> class Bank(): # Let's create a bank, building ATMs
2...    crisis = False
3...    def create_atm(self):
4...        while not self.crisis:
5...            yield "$100"
6>>> hsbc = Bank() # When everything's ok the ATM gives you as much as you want
7>>> corner_street_atm = hsbc.create_atm()
8>>> print(corner_street_atm.next())
9$100
10>>> print(corner_street_atm.next())
11$100
12>>> print([corner_street_atm.next() for cash in range(5)])
13['$100''$100''$100''$100''$100']
14>>> hsbc.crisis = True # Crisis is coming, no more money!
15>>> print(corner_street_atm.next())
16<type 'exceptions.StopIteration'>
17>>> wall_street_atm = hsbc.create_atm() # It's even true for new ATMs
18>>> print(wall_street_atm.next())
19<type 'exceptions.StopIteration'>
20>>> hsbc.crisis = False # The trouble is, even post-crisis the ATM remains empty
21>>> print(corner_street_atm.next())
22<type 'exceptions.StopIteration'>
23>>> brand_new_atm = hsbc.create_atm() # Build a new one to get back in business
24>>> for cash in brand_new_atm:
25...    print cash
26$100
27$100
28$100
29$100
30$100
31$100
32$100
33$100
34$100
35...
复制代码

Itertools, your best friend

itertools包含了用于操做迭代的特殊函数,好比复制、链接ui

 1>>> horses = [1234]
2>>> races = itertools.permutations(horses)
3>>> print(races)
4<itertools.permutations object at 0xb754f1dc>
5>>> print(list(itertools.permutations(horses)))
6[(1234),
7 (1243),
8 (1324),
9 (1342),
10 (1423),
11 (1432),
12 (2134),
13 (2143),
14 (2314),
15 (2341),
16 (2413),
17 (2431),
18 (3124),
19 (3142),
20 (3214),
21 (3241),
22 (3412),
23 (3421),
24 (4123),
25 (4132),
26 (4213),
27 (4231),
28 (4312),
29 (4321)]
复制代码

迭代是实现可迭代(iter()方法)和迭代器(next()方法)的过程。迭代器是容许您在迭代器上迭代的对象。有点绕,实操一下吧。^-^spa

相关文章
相关标签/搜索