(訳)Pythonキーワードyieldの解釈--下編(stackoverflow)
4869 ワード
6.コードに戻る
(訳者注:これはこの質問に答える具体的な解釈です)
ビルダー:
呼び出し元:
このコードにはいくつかの小さな部分が含まれています.リストを反復しますが、反復ではリストが拡張され続けています.無限反復を引き起こす可能性があるため、これらのネストされたデータを反復する簡潔な方法です.candidates.extend(node._get_child_candidates(distance,min_dist,max_dist))はジェネレータのすべての値を使い果たしたが、whileは常に新しいジェネレータを生成し、前回とは異なる値を生成し、同じノードに作用しない以上、whileは絶えず新しいジェネレータを生成する. extend()は反復器に作用し、パラメータを反復器の後ろに追加する反復器法である.
通常、リストパラメータを渡します.
しかし、あなたのコードにはジェネレータがあります.これはいいです.なぜなら、すべての値 を2回読む必要はありませんサブオブジェクトはたくさんありますが、メモリに格納する必要はありません.
Pythonはメソッドのパラメータがリストであるかどうかに関心がないため、これは効果的です.Pythonは反復可能であることを望んでいるので、このパラメータはリスト、メタグループ、文字列、ジェネレータ...これはducktypingと呼ばれています.これもPythonがこんなに素晴らしい理由の一つですが、これはもう別の問題です.
ここで止まって、ジェネレータの高度な使い方を見てみましょう.
7.制御ジェネレータが尽きる
これは、いくつかのリソースへのアクセスを制御するのに役立ちます.
8.Itertools、あなたの親友
itertoolsには多くの特殊な反復法が含まれている.反復器をコピーしたいと思ったことがありますか?2つの反復器を直列に接続しますか?ネストされたリストをグループ化しますか?新しいリストのzip/mapを作成する必要はありませんか?
import itertoolsだけ
例が必要ですか?試合中に4頭の馬がゴールに着く可能性のある順番を見てみましょう.
9.反復器の内部メカニズムを理解する
反復は反復可能なオブジェクト(iter()メソッドを実装)と反復器(next()メソッドを実装)を実装するプロセスである.反復可能オブジェクトは、反復器を取得できる任意のオブジェクトです.反復器は、反復可能なオブジェクトを反復できるオブジェクトです.
もっとこの文章を見てhttp://effbot.org/zone/python-for-statement.htm
(訳者注:これはこの質問に答える具体的な解釈です)
ビルダー:
# Here you create the method of the node object that will return the generator
def node._get_child_candidates(self, distance, min_dist, max_dist):
# Here is the code that will be called each time you use the generator object :
# If there is still a child of the node object on its left
# AND if distance is ok, return the next child
if self._leftchild and distance - max_dist < self._median:
yield self._leftchild
# If there is still a child of the node object on its right
# AND if distance is ok, return the next child
if self._rightchild and distance + max_dist >= self._median:
yield self._rightchild
# If the function arrives here, the generator will be considered empty
# there is no more than two values : the left and the right children
呼び出し元:
# Create an empty list and a list with the current object referenceresult, candidates = list(), [self]
# Loop on candidates (they contain only one element at the beginning)
while candidates:
# Get the last candidate and remove it from the list
node = candidates.pop()
# Get the distance between obj and the candidate
distance = node._get_dist(obj) # If distance is ok, then you can fill the result
if distance <= max_dist and distance >= min_dist:
result.extend(node._values)
# Add the children of the candidate in the candidates list
# so the loop will keep running until it will have looked
# at all the children of the children of the children, etc. of the candidate
candidates.extend(node._get_child_candidates(distance, min_dist, max_dist))
return result
このコードにはいくつかの小さな部分が含まれています.
通常、リストパラメータを渡します.
>>> a = [1, 2]
>>> b = [3, 4]
>>> a.extend(b)
>>> print(a)
[1, 2, 3, 4]
しかし、あなたのコードにはジェネレータがあります.これはいいです.なぜなら、
Pythonはメソッドのパラメータがリストであるかどうかに関心がないため、これは効果的です.Pythonは反復可能であることを望んでいるので、このパラメータはリスト、メタグループ、文字列、ジェネレータ...これはducktypingと呼ばれています.これもPythonがこんなに素晴らしい理由の一つですが、これはもう別の問題です.
ここで止まって、ジェネレータの高度な使い方を見てみましょう.
7.制御ジェネレータが尽きる
>>> class Bank(): # let's create a bank, building ATMs
... crisis = False... def create_atm(self) :
... while not self.crisis :
... yield "$100"
>>> hsbc = Bank() # when everything's ok the ATM gives you as much as you want
>>> corner_street_atm = hsbc.create_atm()
>>> print(corner_street_atm.next())
$100
>>> print(corner_street_atm.next())
$100
>>> print([corner_street_atm.next() for cash in range(5)])
['$100', '$100', '$100', '$100', '$100']
>>> hsbc.crisis = True # crisis is coming, no more money!
>>> print(corner_street_atm.next())
>>> wall_street_atm = hsbc.create_atm() # it's even true for new ATMs
>>> print(wall_street_atm.next())
>>> hsbc.crisis = False # trouble is, even post-crisis the ATM remains empty
>>> print(corner_street_atm.next())
>>> brand_new_atm = hsbc.create_atm() # build a new one to get back in business
>>> for cash in brand_new_atm :
... print cash
$100
$100
$100
$100
$100
$100
$100
$100
$100
...
これは、いくつかのリソースへのアクセスを制御するのに役立ちます.
8.Itertools、あなたの親友
itertoolsには多くの特殊な反復法が含まれている.反復器をコピーしたいと思ったことがありますか?2つの反復器を直列に接続しますか?ネストされたリストをグループ化しますか?新しいリストのzip/mapを作成する必要はありませんか?
import itertoolsだけ
例が必要ですか?試合中に4頭の馬がゴールに着く可能性のある順番を見てみましょう.
>>> horses = [1, 2, 3, 4]
>>> races = itertools.permutations(horses)
>>> print(races)
>>> print(list(itertools.permutations(horses)))
[(1, 2, 3, 4),
(1, 2, 4, 3),
(1, 3, 2, 4),
(1, 3, 4, 2),
(1, 4, 2, 3),
(1, 4, 3, 2),
(2, 1, 3, 4),
(2, 1, 4, 3),
(2, 3, 1, 4),
(2, 3, 4, 1),
(2, 4, 1, 3),
(2, 4, 3, 1),
(3, 1, 2, 4),
(3, 1, 4, 2),
(3, 2, 1, 4),
(3, 2, 4, 1),
(3, 4, 1, 2),
(3, 4, 2, 1),
(4, 1, 2, 3),
(4, 1, 3, 2),
(4, 2, 1, 3),
(4, 2, 3, 1),
(4, 3, 1, 2),
(4, 3, 2, 1)]
9.反復器の内部メカニズムを理解する
反復は反復可能なオブジェクト(iter()メソッドを実装)と反復器(next()メソッドを実装)を実装するプロセスである.反復可能オブジェクトは、反復器を取得できる任意のオブジェクトです.反復器は、反復可能なオブジェクトを反復できるオブジェクトです.
もっとこの文章を見てhttp://effbot.org/zone/python-for-statement.htm