The problem is easy, I want to iterate over each element of the list and the next one in pairs (wrapping the last one with the first).
I've thought about two unpythonic ways of doing it:
def pairs(lst): n = len(lst) for i in range(n): yield lst[i],lst[(i+1)%n]
and:
def pairs(lst): return zip(lst,lst[1:]+[lst[:1]])
expected output:
>>> for i in pairs(range(10)): print i (0, 1) (1, 2) (2, 3) (3, 4) (4, 5) (5, 6) (6, 7) (7, 8) (8, 9) (9, 0) >>>
any suggestions about a more pythonic way of doing this? maybe there is a predefined function out there I haven't heard about?
also a more general n-fold (with triplets, quartets, etc. instead of pairs) version could be interesting.
combinations: A better way to iterate through a pair of values in a Python list. If you want to iterate through a pair of values in a list and the order does not matter ( (a,b) is the same as (b, a) ), use itertools. combinations instead of two for loops.
You can loop through the list items by using a while loop. Use the len() function to determine the length of the list, then start at 0 and loop your way through the list items by referring to their indexes. Remember to increase the index by 1 after each iteration.
Care has to be taken while pairing the last element with the first one to form a cyclic pair. zip function can be used to extract pairs over the list and slicing can be used to successively pair the current element with the next one for the efficient pairing.
Yes, it should, every time, since lists are ordered. If you are iterating over a dict , the order may be different than expected. Python dicts are unordered.
def pairs(lst): i = iter(lst) first = prev = item = i.next() for item in i: yield prev, item prev = item yield item, first
Works on any non-empty sequence, no indexing required.
I've coded myself the tuple general versions, I like the first one for it's ellegant simplicity, the more I look at it, the more Pythonic it feels to me... after all, what is more Pythonic than a one liner with zip, asterisk argument expansion, list comprehensions, list slicing, list concatenation and "range"?
def ntuples(lst, n): return zip(*[lst[i:]+lst[:i] for i in range(n)])
The itertools version should be efficient enough even for large lists...
from itertools import * def ntuples(lst, n): return izip(*[chain(islice(lst,i,None), islice(lst,None,i)) for i in range(n)])
And a version for non-indexable sequences:
from itertools import * def ntuples(seq, n): iseq = iter(seq) curr = head = tuple(islice(iseq, n)) for x in chain(iseq, head): yield curr curr = curr[1:] + (x,)
Anyway, thanks everybody for your suggestions! :-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With