for row_number, row in enumerate(cursor):
Pythonでは何をしますか?
enumerate
この文脈ではどういう意味ですか?
for row_number, row in enumerate(cursor):
Pythonでは何をしますか?
enumerate
この文脈ではどういう意味ですか?
回答:
このenumerate()
関数は、イテラブルにカウンターを追加します。
したがって、の要素ごとcursor
に、タプルがで生成され(counter, element)
ます。for
ループが結合することrow_number
とrow
、それぞれ。
デモ:
>>> elements = ('foo', 'bar', 'baz')
>>> for elem in elements:
... print elem
...
foo
bar
baz
>>> for count, elem in enumerate(elements):
... print count, elem
...
0 foo
1 bar
2 baz
デフォルトでenumerate()
は、からカウントを開始します0
が、2番目の整数引数を指定すると、代わりにその数値から開始されます。
>>> for count, elem in enumerate(elements, 42):
... print count, elem
...
42 foo
43 bar
44 baz
enumerate()
Pythonで再実装する場合、これを実現する2つの方法があります。1つitertools.count()
はカウントを行うために使用し、もう1つはジェネレータ関数で手動でカウントします。
from itertools import count
def enumerate(it, start=0):
# return an iterator that adds a counter to each element of it
return zip(count(start), it)
そして
def enumerate(it, start=0):
count = start
for elem in it:
yield (count, elem)
count += 1
Cでの実際の実装は後者に近く、一般的なfor i, ...
アンパックの場合に単一のタプルオブジェクトを再利用する最適化と、Python整数オブジェクト(これは、無制限)。
これは、反復可能なオブジェクトを返す組み込み関数です。ドキュメントを見る。
要するに、それはタプルに結合されたイテラブル(リストのような)の要素とインデックス番号をループします:
for item in enumerate(["a", "b", "c"]):
print item
プリント
(0, "a")
(1, "b")
(2, "c")
シーケンス(または他の反復可能なもの)をループしたい場合、およびインデックスカウンターを利用可能にしたい場合に役立ちます。カウンタを他の値(通常は1)から開始する場合は、それを2番目の引数としてに指定できenumerate
ます。
item
、あなたは括弧を削除することができます:D
yield
/ を使用するyield from
か、暗黙的にジェネレーター式を使用しyield
ます)。enumerate
ジェネレータではありません。すべてのダックタイピングに関連する目的には違いはありませんが、明示的な型チェックとPython言語のドキュメントでは、「ジェネレータ」という用語を1つの目的でのみ使用していますenumerate
。
私は本(読んでい効果的なのPythonをブレット・スラットキンにより)、彼は、リストを反復処理しても、リスト内の現在の項目のインデックスを知るための別の方法を示していたが、彼は、それはそれを使用すると、使用することをお勧めではないことを示唆しているenumerate
代わりに。列挙の意味を尋ねたのは知っていましたが、次のことを理解したときenumerate
、現在のアイテムのインデックスを簡単に(そして読みやすく)しながらリストを反復する方法も理解しました。
list_of_letters = ['a', 'b', 'c']
for i in range(len(list_of_letters)):
letter = list_of_letters[i]
print (i, letter)
出力は次のとおりです。
0 a
1 b
2 c
enumerate
機能について読む前に、私は何かをしていました。
i = 0
for n in list_of_letters:
print (i, n)
i += 1
同じ出力を生成します。
しかし、enumerate
私はただ書く必要があります:
list_of_letters = ['a', 'b', 'c']
for i, letter in enumerate(list_of_letters):
print (i, letter)
他のユーザーが述べたように、 enumerate
に、イテラブルの各アイテムの隣に増分インデックスを追加するジェネレータがあります。
したがって、リストにとあるl = ["test_1", "test_2", "test_3"]
場合、list(enumerate(l))
次のような結果になります。[(0, 'test_1'), (1, 'test_2'), (2, 'test_3')]
。
さて、これが便利なのはいつですか?考えられる使用例は、アイテムを反復処理したい場合、およびリスト内のインデックスのみを知っていて、その値はわかっていない特定のアイテムをスキップしたい場合です(その時点では値が不明であるため)。
for index, value in enumerate(joint_values):
if index == 3:
continue
# Do something with the other `value`
したがって、通常のforループを使用してコードを読み取ることもできますがrange
、アイテムにアクセスするには、それらにインデックスを付ける必要があります(つまり、joint_values[i]
)。
別のユーザーがenumerate
を使用した実装について言及しましたがzip
、私は使用せずに、より純粋な(しかし少し複雑な)方法をitertools
以下のように考えています:
def enumerate(l, start=0):
return zip(range(start, len(l) + start), l)
例:
l = ["test_1", "test_2", "test_3"]
enumerate(l)
enumerate(l, 10)
出力:
[(0、 'test_1')、(1、 'test_2')、(2、 'test_3')]
[(10、 'test_1')、(11、 'test_2')、(12、 'test_3')]
コメントで述べたように、範囲を使用したこのアプローチは、元のenumerate
関数のように任意のイテラブルでは機能しません。
itertools
は、あなたのrange
アプローチはコンテナでのみ機能するためです。enumerate
任意のイテラブルで動作します。ファイルを反復処理したい場合はfor lineno, line in enumerate(myfile):
機能しますが、range(len(myfile))
EOFに達するまで長さがわからないため、実行できませんでした。
列挙関数は次のように機能します。
doc = """I like movie. But I don't like the cast. The story is very nice"""
doc1 = doc.split('.')
for i in enumerate(doc1):
print(i)
出力は
(0, 'I like movie')
(1, " But I don't like the cast")
(2, ' The story is very nice')