ループ内でインデックスのみを使用したい場合は、_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
..をサポートしていないオブジェクトでは壊れます。
これはまれな要件です。コンテナから使用される情報は、その長さだけです。この場合、私は確かにこの事実を明示し、最初のバージョンを使用します。
xrangeは少し高速になるはずですが、列挙すると、結局p
が必要であることに気付いたときに変更する必要がないことを意味します。
サンプルコードに基づいて、
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]
時間テストを実行したところ、範囲が列挙よりも約2倍速いことがわかりました。 (on python 3.6 for Win32)
len(a)= 1Mの場合、ベスト3
それが役に立てば幸い。
参考:私は最初にこのテストを開始してpython vs vbaの速度を比較しました...そしてvbaは実際には範囲メソッドよりも7倍速いことがわかりました...それは私の貧弱なpythonスキル?
確かにpythonはどういうわけかvbaよりもうまくいくことができます
列挙するためのスクリプト
import time
a = [0]
a = a * 1000000
time.perf_counter()
for i,j in enumerate(a):
pass
print(time.perf_counter())
範囲のスクリプト
import time
a = [0]
a = a * 1000000
time.perf_counter()
for i in range(len(a)):
pass
print(time.perf_counter())
vbaのスクリプト(0.008秒)
Sub timetest_for()
Dim a(1000000) As Byte
Dim i As Long
tproc = Timer
For i = 1 To UBound(a)
Next i
Debug.Print Timer - tproc
End Sub
私はそれをテストしたかったのでこれを書きました。したがって、使用する値が必要かどうかによって異なります。
コード:
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