微信公衆號: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