微信公众号: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
复制代码
全部可用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
复制代码
生成器都是可迭代的,只是只能迭代一次。由于生成器不存储全部值到内存中,而是动态的生成值。 微信
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>
复制代码
用法同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
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包含了用于操做迭代的特殊函数,好比复制、链接ui
1>>> horses = [1, 2, 3, 4]
2>>> races = itertools.permutations(horses)
3>>> print(races)
4<itertools.permutations object at 0xb754f1dc>
5>>> print(list(itertools.permutations(horses)))
6[(1, 2, 3, 4),
7 (1, 2, 4, 3),
8 (1, 3, 2, 4),
9 (1, 3, 4, 2),
10 (1, 4, 2, 3),
11 (1, 4, 3, 2),
12 (2, 1, 3, 4),
13 (2, 1, 4, 3),
14 (2, 3, 1, 4),
15 (2, 3, 4, 1),
16 (2, 4, 1, 3),
17 (2, 4, 3, 1),
18 (3, 1, 2, 4),
19 (3, 1, 4, 2),
20 (3, 2, 1, 4),
21 (3, 2, 4, 1),
22 (3, 4, 1, 2),
23 (3, 4, 2, 1),
24 (4, 1, 2, 3),
25 (4, 1, 3, 2),
26 (4, 2, 1, 3),
27 (4, 2, 3, 1),
28 (4, 3, 1, 2),
29 (4, 3, 2, 1)]
复制代码
迭代是实现可迭代(iter()方法)和迭代器(next()方法)的过程。迭代器是容许您在迭代器上迭代的对象。有点绕,实操一下吧。^-^spa