ループ内でインデックスのみを使用したい場合は、range/xrange
関数を組み合わせて使用する必要がありますlen()
a = [1,2,3]
for i in xrange(len(a)):
print i
またはenumerate
?全く使わなくp
ても?
for i,p in enumerate(a):
print i
より一般的なものとして使用enumerate
します-たとえば、イテラブルとシーケンスで機能し、オブジェクトへの参照を返すだけのオーバーヘッドはそれほど大きな問題ではありません-一方xrange(len(something))
、(私にとっては)意図どおりに読みやすくなりますが- len
...をサポートしていないオブジェクトで中断する
lenでxrangeを使用することは非常に一般的なユースケースであるため、インデックスで値にアクセスする必要がある場合にのみ使用できます。
ただし、何らかの理由で列挙を使用する場合は、アンダースコア(_)を使用できます。これは、変数を意味のある方法で使用しないことを示す、よく見られる表記です。
for i, _ in enumerate(a):
print i
アンダースコア(_)を使用して発生する可能性のある落とし穴もあります。i18nライブラリおよびシステムでは「translating」関数に_という名前を付けることも一般的であるため、gettextまたはそのような種類の他のライブラリ(@lazyrに感謝)で使用することに注意してください。
これはまれな要件です。コンテナから使用される情報はその長さだけです。この場合、私は実際にこの事実を明示し、最初のバージョンを使用します。
p
xrangeは少し高速になるはずですが、 enumerate は、結局必要であることに気付いたときに変更する必要がないことを意味します
テストしたかったので書きました。したがって、使用する値が必要かどうかによって異なります。
コード:
testlist = []
for i in range(10000):
testlist.append(i)
def rangelist():
a = 0
for i in range(len(testlist)):
a += i
a = testlist[i] + 1 # Comment this line for example for testing
def enumlist():
b = 0
for i, x in enumerate(testlist):
b += i
b = x + 1 # Comment this line for example for testing
import timeit
t = timeit.Timer(lambda: rangelist())
print("range(len()):")
print(t.timeit(number=10000))
t = timeit.Timer(lambda: enumlist())
print("enum():")
print(t.timeit(number=10000))
これで実行できるようになり、結果が得られる可能性が高くなり、enum() の方が高速です。ソースをコメントするa = testlist[i] + 1
と、 b = x + 1
range(len()) の方が高速であることがわかります。
上記のコードでは、次のようになります。
range(len()):
18.766527627612255
enum():
15.353173553868345
上記のようにコメントすると、次のようになります。
range(len()):
8.231641875551514
enum():
9.974262515773656
サンプルコードに基づいて、
res = [[profiel.attr[i].x for i,p in enumerate(profiel.attr)] for profiel in prof_obj]
私はそれを
res = [[p.x for p in profiel.attr] for profiel in prof_obj]
を使用するだけrange()
です。とにかくすべてのインデックスを使用する場合、xrange()
実際の利点はありません(len(a)
本当に大きい場合を除く)。そしてenumerate()
、すぐに捨てるより豊かなデータ構造を作成します。