私は現在、Pythonの数独ソルバーに関するこの投稿をレビューしています。私はそれを一行ずつ分解しようとしています、そして私は以下を経験しました
digits = '123456789'
rows = 'ABCDEFGHI'
cols = digits
#squares will give you all the squares of a Sudoku, from A1-A9 to I1-I9
squares = cross(rows, cols)
unitlist = ([cross(rows, c) for c in cols] +
[cross(r, cols) for r in rows] +
[cross(rs, cs) for rs in ('ABC','DEF','GHI') for cs in ('123','456','789')])
#each square has 3 units : the row it is in, the column it is in, and the "block" of 3x3 squares it is in :
units = dict((s, [u for u in unitlist if s in u])
for s in squares)
その最後の部分は私を唖然とさせるものです。私が間違っていなければ、ジェネレーターの中にリスト内包表記があります。しかし、dict関数内で「for s insquares」は何をしているのでしょうか?次のように書いて同じ結果が得られないのはなぜですか?
for s in squares :
units3 = dict((s, [u for u in unitlist if s in u]))
これは私にはかなりわかりにくいようですが、残念ながら、このためのリソースを見つけようとする私の試みはすべて、dictの作成に関する基本的なチュートリアル、またはdict値のループを指す結果になります...
dict関数内のforループがどのように機能するかを教えてください。または、そのトピックに関する優れたチュートリアルを教えてください。
これはリスト内包表記ではなく、ジェネレータ式です。この2つは関連していますが、リストは作成されていません。ジェネレーター式はジェネレーターオブジェクトを生成します。これは遅延して繰り返すことができ、各ステップでループ式が実行されます。
たとえば、次のような式を作成して二乗を計算できます。
>>> squares = (i ** 2 for i in range(10))
>>> squares
<generator object <genexpr> at 0x10c832468>
>>> next(squares)
0
>>> next(squares)
1
>>> next(squares)
4
このnext()
関数は、イテレータを進めて次の値を生成します。その間、ジェネレーターは一時停止し、残りの値はまだ計算されていません。
見つけた例では、ジェネレータ式がdict()
呼び出しの唯一の引数(...)
です。この場合、ジェネレータ式のforは省略できます。書くこともできdict((...))
、まったく同じ結果が得られます。呼び出しに複数の引数が必要な場合は、代わりにそれらの括弧が必要になります。dict(...)
ジェネレータ式の中にネストされているのは、ディクショナリ値のみのリスト内包表記です。
ジェネレーターは(key, value)
タプルを生成し、dict()
呼び出し可能オブジェクトはこれを使用して辞書を作成します。dict()
ドキュメントを参照してください:
[...]それ以外の場合、位置引数は反復可能なオブジェクトである必要があります。iterableの各アイテムは、それ自体が正確に2つのオブジェクトを持つiterableである必要があります。各アイテムの最初のオブジェクトが新しいディクショナリのキーになり、2番目のオブジェクトが対応する値になります。
したがって、同等のfor
ループステートメントは次のようになります。
units = {}
for s in squares:
units[s] = [u for u in unitlist if s in u]
[u for u in unitlist if s in u]
リスト内包に注意してください。これは、ジェネレーター式から独立した別個の式です(ただし、s
毎回の現在の値を使用します)。ループは、ここで事前に作成する必要のあるディクショナリに値を設定しますが、それ以外の場合、反復可能な各ステップの結果は同じです。キーs
は、値としてリスト内包表記の結果で設定されます。
Python2.7およびPython3では、ジェネレーター式の代わりに、辞書内包表記を使用してまったく同じ辞書を作成できます。
units = {s: [u for u in unitlist if s in u] for s in squares}
辞書理解のパターンは{<key expression>: <value expression> for ... in ... <optionally more if filters and for loops>}
;です。これを、dict((<key expression>, <value expression>) for ... in ... <optionally more if filters and for loops>)
見つけたコードで使用されているパターンと比較してください。インタプリタは、各ステップでジェネレータ式を停止および開始する方法を心配する必要がなく、dict
名前を見つけて呼び出す必要もないため、辞書の理解が速くなります。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加