只有索引所需:枚举或(x)的范围是多少?(Only index needed: enumerate

2019-06-17 17:14发布

如果我想在一个循环中只使用索引,我应该更好地使用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    

Answer 1:

我会用enumerate ,因为它是更通用的-例如,它会在iterables和序列工作,只是返回的对象引用开销不是什么大不了的事-而xrange(len(something))虽然(我)更容易阅读为你的意图-将打破上的对象,且不支持len ...



Answer 2:

这是一个难得的要求 - 从容器中使用的唯一信息是它的长度! 在这种情况下,我确实使这一事实明确,使用的第一个版本。



Answer 3:

使用的xrange与LEN是一个相当常见的情况,所以是的,你可以使用它,如果你只需要通过索引来访问值。

但是,如果你喜欢用枚举出于某种原因,你可以使用下划线(_),它只是一个经常看到的符号,告诉你不会在一些有意义的方式使用该变量:

for i, _ in enumerate(a):
    print i

还有可能发生使用下划线(_)一个陷阱。 这也是常见的名字“翻译”功能_在国际化库和系统,所以要小心与gettext的或这样那样的一些其他图书馆(thnks到@lazyr)使用它。



Answer 4:

x范围应该是快一点,但枚举将意味着你不需要改变它,当你意识到你需要p毕竟



Answer 5:

根据您的示例代码,

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]


Answer 6:

我写了这个,因为我想对它进行测试。 所以,这取决于你所需要的值进行工作。

码:

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))

现在,您可以运行它,并会得到最有可能的结果是,枚举()更快。 当你在评论源a = testlist[i] + 1b = x + 1 ,你会看到的范围(LEN())更快。

对于上面我的代码得到:

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

现在,上述评论是我说的时候得到:

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


Answer 7:

我跑了一次测试,发现超范围大约为2x比枚举更快。 (有关python 3.6为Win32)

最好的如图3所示,LEN(A)= 1M

  • 列举的(a):0.125秒
  • 范围(LEN(A)):0.058s

希望能帮助到你。

FYI:我initialy开始这个测试来比较蟒蛇VS VBA的速度......并且发现了VBA实际上7X比范围方法快...是的,因为我那可怜的蟒蛇技能?

当然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.008s)

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


Answer 8:

只要使用range() 如果你还是要用的所有索引, xrange()不提供任何实际的好处(除非len(a)是真正的大)。 和enumerate()创建一个你会立即扔掉了更丰富的数据结构。



文章来源: Only index needed: enumerate or (x)range?