Pairwise circular Python 'for' loop

后端 未结 18 832
执念已碎
执念已碎 2020-12-24 10:24

Is there a nice Pythonic way to loop over a list, retuning a pair of elements? The last element should be paired with the first.

So for instance, if I have the list

相关标签:
18条回答
  • 2020-12-24 10:51

    I would use a list comprehension, and take advantage of the fact that l[-1] is the last element.

    >>> l = [1,2,3]
    >>> [(l[i-1],l[i]) for i in range(len(l))]
    [(3, 1), (1, 2), (2, 3)]
    

    You don't need a temporary list that way.

    0 讨论(0)
  • 2020-12-24 10:51

    Just another try

    >>> L = [1,2,3]
    >>> zip(L,L[1:]) + [(L[-1],L[0])]
    [(1, 2), (2, 3), (3, 1)]
    
    0 讨论(0)
  • 2020-12-24 10:52

    this seems like combinations would do the job.

    from itertools import combinations
    x=combinations([1,2,3],2)
    

    this would yield a generator. this can then be iterated over as such

    for i in x:
      print i
    

    the results would look something like

    (1, 2)
    (1, 3)
    (2, 3)
    
    0 讨论(0)
  • 2020-12-24 10:53

    How about this?

    li = li+[li[0]]
    pairwise = [(li[i],li[i+1]) for i in range(len(li)-1)]
    
    0 讨论(0)
  • 2020-12-24 10:55

    I'd use a slight modification to the pairwise recipe from the itertools documentation:

    def pairwise_circle(iterable):
        "s -> (s0,s1), (s1,s2), (s2, s3), ... (s<last>,s0)"
        a, b = itertools.tee(iterable)
        first_value = next(b, None)
        return itertools.zip_longest(a, b,fillvalue=first_value)
    

    This will simply keep a reference to the first value and when the second iterator is exhausted, zip_longest will fill the last place with the first value.

    (Also note that it works with iterators like generators as well as iterables like lists/tuples.)

    Note that @Barry's solution is very similar to this but a bit easier to understand in my opinion and easier to extend beyond one element.

    0 讨论(0)
  • 2020-12-24 10:55

    In the upcoming Python 3.10 release schedule, the new pairwise function provides a way to create sliding pairs of consecutive elements:

    from itertools import pairwise
    
    # l = [1, 2, 3]
    list(pairwise(l + l[:1]))
    # [(1, 2), (2, 3), (3, 1)]
    

    or simply pairwise(l + l[:1]) if you don't need the result as a list.


    Note that we pairwise on the list appended with its head (l + l[:1]) so that rolling pairs are circular (i.e. so that we also include the (3, 1) pair):

    list(pairwise(l)) # [(1, 2), (2, 3)]
    l + l[:1] # [1, 2, 3, 1]
    
    0 讨论(0)
提交回复
热议问题