Is there a need for range(len(a))?

后端 未结 11 662
执念已碎
执念已碎 2020-12-02 05:05

One frequently finds expressions of this type in python questions on SO. Either for just accessing all items of the iterable

for i in range(len(a)):
    prin         


        
相关标签:
11条回答
  • 2020-12-02 05:48

    Very simple example:

    def loadById(self, id):
        if id in range(len(self.itemList)):
            self.load(self.itemList[id])
    

    I can't think of a solution that does not use the range-len composition quickly.

    But probably instead this should be done with try .. except to stay pythonic i guess..

    0 讨论(0)
  • 2020-12-02 05:49

    If you need to work with indices of a sequence, then yes - you use it... eg for the equivalent of numpy.argsort...:

    >>> a = [6, 3, 1, 2, 5, 4]
    >>> sorted(range(len(a)), key=a.__getitem__)
    [2, 3, 1, 5, 4, 0]
    
    0 讨论(0)
  • 2020-12-02 05:49

    Going by the comments as well as personal experience, I say no, there is no need for range(len(a)). Everything you can do with range(len(a)) can be done in another (usually far more efficient) way.

    You gave many examples in your post, so I won't repeat them here. Instead, I will give an example for those who say "What if I want just the length of a, not the items?". This is one of the only times you might consider using range(len(a)). However, even this can be done like so:

    >>> a = [1, 2, 3, 4]
    >>> for _ in a:
    ...     print True
    ...
    True
    True
    True
    True
    >>>
    

    Clements answer (as shown by Allik) can also be reworked to remove range(len(a)):

    >>> a = [6, 3, 1, 2, 5, 4]
    >>> sorted(range(len(a)), key=a.__getitem__)
    [2, 3, 1, 5, 4, 0]
    >>> # Note however that, in this case, range(len(a)) is more efficient.
    >>> [x for x, _ in sorted(enumerate(a), key=lambda i: i[1])]
    [2, 3, 1, 5, 4, 0]
    >>>
    

    So, in conclusion, range(len(a)) is not needed. Its only upside is readability (its intention is clear). But that is just preference and code style.

    0 讨论(0)
  • 2020-12-02 05:49

    Sometimes matplotlib requires range(len(y)), e.g., while y=array([1,2,5,6]), plot(y) works fine, scatter(y) does not. One has to write scatter(range(len(y)),y). (Personally, I think this is a bug in scatter; plot and its friends scatter and stem should use the same calling sequences as much as possible.)

    0 讨论(0)
  • 2020-12-02 05:54

    Sometimes, you really don't care about the collection itself. For instance, creating a simple model fit line to compare an "approximation" with the raw data:

    fib_raw = [1, 1, 2, 3, 5, 8, 13, 21] # Fibonacci numbers
    
    phi = (1 + sqrt(5)) / 2
    phi2 = (1 - sqrt(5)) / 2
    
    def fib_approx(n): return (phi**n - phi2**n) / sqrt(5)
    
    x = range(len(data))
    y = [fib_approx(n) for n in x]
    
    # Now plot to compare fib_raw and y
    # Compare error, etc
    

    In this case, the values of the Fibonacci sequence itself were irrelevant. All we needed here was the size of the input sequence we were comparing with.

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