Only index needed: enumerate or (x)range?

后端 未结 8 2138
长发绾君心
长发绾君心 2020-11-29 09:46

If I want to use only the index within a loop, should I better use the range/xrange function in combination with len()

a = [1,2,3]         


        
相关标签:
8条回答
  • 2020-11-29 10:24

    I would use enumerate as it's more generic - eg it will work on iterables and sequences, and the overhead for just returning a reference to an object isn't that big a deal - while xrange(len(something)) although (to me) more easily readable as your intent - will break on objects with no support for len...

    0 讨论(0)
  • 2020-11-29 10:26

    xrange should be a little faster, but enumerate will mean you don't need to change it when you realise that you need p afterall

    0 讨论(0)
  • 2020-11-29 10:28

    That's a rare requirement – the only information used from the container is its length! In this case, I'd indeed make this fact explicit and use the first version.

    0 讨论(0)
  • 2020-11-29 10:31

    Based on your sample code,

    res = [[profiel.attr[i].x for i,p in enumerate(profiel.attr)] for profiel in prof_obj]
    

    I would replace it with

    res = [[p.x for p in profiel.attr] for profiel in prof_obj]
    
    0 讨论(0)
  • 2020-11-29 10:34

    I ran a time test and found out range is about 2x faster than enumerate. (on python 3.6 for Win32)

    best of 3, for len(a) = 1M

    • enumerate(a): 0.125s
    • range(len(a)): 0.058s

    Hope it helps.

    FYI: I initialy started this test to compare python vs vba's speed...and found out vba is actually 7x faster than range method...is it because of my poor python skills?

    surely python can do better than vba somehow

    script for enumerate

    import time
    a = [0]
    a = a * 1000000
    time.perf_counter()
    
    for i,j in enumerate(a):
        pass
    
    print(time.perf_counter())
    

    script for range

    import time
    a = [0]
    a = a * 1000000
    time.perf_counter()
    
    for i in range(len(a)):
        pass
    
    print(time.perf_counter())
    

    script for 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
    
    0 讨论(0)
  • 2020-11-29 10:43

    Just use range(). If you're going to use all the indexes anyway, xrange() provides no real benefit (unless len(a) is really large). And enumerate() creates a richer datastructure that you're going to throw away immediately.

    0 讨论(0)
提交回复
热议问题