次のコードがあります。
letters = 'defghijklmno'
K = {letters[i]:(i*i-1) for i in range(len(letters))}
文字のシーケンス変数と値の計算方法を繰り返し処理していることは理解していますが、文字列の個々の文字にキーを設定する方法について混乱しています。特に、文字がキーとしてインデックス化されているためです。基本的に、私はpythonがこの式をどのように評価するかを理解しようとしています
次のコードがあります。
letters = 'defghijklmno'
K = {letters[i]:(i*i-1) for i in range(len(letters))}
文字のシーケンス変数と値の計算方法を繰り返し処理していることは理解していますが、文字列の個々の文字にキーを設定する方法について混乱しています。特に、文字がキーとしてインデックス化されているためです。基本的に、私はpythonがこの式をどのように評価するかを理解しようとしています
説明:
>>> letters = 'defghijklmno'
>>> range(len(letters))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
この意味は
>>> [letters[i] for i in range(len(letters))]
['d', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o']
同時に
>>> [(i*i-1) for i in range(len(letters))]
[-1, 0, 3, 8, 15, 24, 35, 48, 63, 80, 99, 120]
したがって、辞書の理解はペアのdict 'd':-1, 'e':0, 'f':3, ...
(など)を構築します。
そのdict
理解は、基本的に次の同義語です。
k = {}
for i in range(len(letters)):
k[letters[i]] = i*i - 1
違いは、外側のスコープを使用する代わりに、新しいスコープを作成することです。
>>> letters = 'defghijklmno'
>>> K = {letters[i]:(i*i-1) for i in range(len(letters))}
>>> i # was defined in an inner scope
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'i' is not defined
>>> k = {}
>>> for i in range(len(letters)):
... k[letters[i]] = i*i - 1
...
>>> i # still defined!
11
まず第一に、これはかなり悪い方法です。インデックスによるループは、Python では非常に悪い習慣です (遅く、読むのが恐ろしい) ので、より良い方法は次のとおりです。
letters = 'defghijklmno'
K = {letter: (i*i-1) for i, letter in enumerate(letters)}
これはすべて、単純な辞書内包表記です。文字列をループすると、それを構成する個々の文字が取得されます。ビルトインを使用しenumerate()
て一致する数値を取得し、文字から 2 乗マイナス 1 までの辞書を作成します。
内包表記自体に苦労している場合は、for ループと同等です (高速であることを除けば)。従兄弟 (リスト/セット内包表記とジェネレーター式) と共に辞書内包表記の例を含む完全な説明については、私のビデオをご覧になることをお勧めします。
Dictの理解をループのように書き直すことができます
K = {} # empty dict
for i in range(len(letters)): # i goes from 0 to 11
K[letters[i]] = i*i-1
したがって、1回の反復で
K['d'] = -1
K['e'] = 0
K['f'] = 3
# ...
等々。dictの理解は、このループを書くためのより短い(そしてほとんどのPythonプログラマーの意見では)よりエレガントな方法です。
それを理解するために、それは何が起こるかの個々の部分を見ることを助けます。ループは、文字のfor i in range(len(letters))
個々の文字ではなく、文字列のインデックスをループします。これは、インデックスを使用して文字列の個々の文字にアクセスできるためです。つまり、最初の文字、 2番目の文字、最後のletters[0]
文字を指します。letters[1]
letters[len(letters)-1]
それでは、辞書のキーを個別に見てみましょう。
>>> [letters[i] for i in range(len(letters))]
['d', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o']
したがって、すべての文字を元の順序で個別に取得します。
それでは、辞書の値を見てみましょう。
>>> [(i*i-1) for i in range(len(letters))]
[-1, 0, 3, 8, 15, 24, 35, 48, 63, 80, 99, 120]
これで、キーと値の両方ができました。辞書の理解が今行うことは、これらのキーを上記の順序で値にリンクすることだけです。
i
from i == 0
to i == 11
(の最後の文字のインデックス)ごとletters
に、結果のディクショナリにエントリが追加されます。ここで、キーはletters[i]
であり、関連する値はi*i-1
です。これは与える:
K['d'] == -1
K['e'] == 0
K['f'] == 3
等々。
2 行目は辞書内包表記です。これは、ディクショナリを形成するために使用されるキーと値のペアを生成することを除いて、通常のリスト内包表記またはジェネレータ式に似ています。
コードはほぼ同等です
letters = 'defghijklmno'
K = {}
for i in range(len(letters)):
key = letters[i]
val = (i*i-1)
K[key] = val
letters
、それ自体の文字を実際に繰り返し処理しているわけではありません。むしろ、から、、、 ...、 まで変化させることで、 の長さを反復しています。変化するにつれて、キーが の番目の文字で値が であるディクショナリ エントリを作成します。letters
i
0
1
2
11
i
i
letters
i*i - 1
つまり、辞書を作成します。各エントリは、のインデックスの 2 乗からマイナス を引いた値とペアになった の文字 (キー)k
で構成されます。letters
k
1
平易な英語での辞書理解は、次のように読むことができます: indexと valuek
を組み合わせたすべての文字 (キー) の辞書。letters
i
i*i - 1