web-dev-qa-db-ja.com

必要なインデックスのみ:列挙または(x)範囲?

ループ内でインデックスのみを使用したい場合は、_range/xrange_関数をlen()と組み合わせて使用​​する方がよいでしょう。

_a = [1,2,3]
for i in xrange(len(a)):
    print i 
_

またはenumeratepをまったく使用しない場合でも?

_for i,p in enumerate(a):
    print i    
_
29
LarsVegas

enumerateを使用するのは、より一般的であるためです。たとえば、反復可能オブジェクトとシーケンスで機能し、オブジェクトへの参照を返すだけのオーバーヘッドはそれほど大きな問題ではありませんが、xrange(len(something)) (私にとって)あなたの意図としてより読みやすくなりますが-len ..をサポートしていないオブジェクトでは壊れます。

17
Jon Clements

これはまれな要件です。コンテナから使用される情報は、その長さだけです。この場合、私は確かにこの事実を明示し、最初のバージョンを使用します。

16
Sven Marnach

xrangeは少し高速になるはずですが、列挙すると、結局pが必要であることに気付いたときに変更する必要がないことを意味します。

4
John La Rooy

サンプルコードに基づいて、

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]
0
Hugh Bothwell

時間テストを実行したところ、範囲が列挙よりも約2倍速いことがわかりました。 (on python 3.6 for Win32)

len(a)= 1Mの場合、ベスト3

  • 列挙(a):0.125秒
  • range(len(a)):0.058s

それが役に立てば幸い。

参考:私は最初にこのテストを開始して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
0
RichieV

私はそれをテストしたかったのでこれを書きました。したがって、使用する値が必要かどうかによって異なります。

コード:

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] + 1b = x + 1でソースにコメントすると、range(len())の方が高速であることがわかります。

上記のコードの場合、次のようになります。

range(len()):
18.766527627612255
enum():
15.353173553868345

上記のようにコメントすると、次のようになります。

range(len()):
8.231641875551514
enum():
9.974262515773656
0
user136036