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 unpyth
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.
This might be satisfactory:
def pairs(lst):
for i in range(1, len(lst)):
yield lst[i-1], lst[i]
yield lst[-1], lst[0]
>>> a = list(range(5))
>>> for a1, a2 in pairs(a):
... print a1, a2
...
0 1
1 2
2 3
3 4
4 0
If you like this kind of stuff, look at python articles on wordaligned.org. The author has a special love of generators in python.
def pairs(ex_list):
for i, v in enumerate(ex_list):
if i < len(list) - 1:
print v, ex_list[i+1]
else:
print v, ex_list[0]
Enumerate returns a tuple with the index number and the value. I print the value and the following element of the list ex_list[i+1]
. The if i < len(list) - 1
means if v is not the last member of the list. If it is: print v and the first element of the list print v, ex_list[0]
.
You can make it return a list. Just append the printed tuples to a list and return it.
def pairs(ex_list):
result = []
for i, v in enumerate(ex_list):
if i < len(list) - 1:
result.append((v, ex_list[i+1]))
else:
result.append((v, ex_list[0]))
return result
Of course, you can always use a deque:
from collections import deque
from itertools import *
def pairs(lst, n=2):
itlst = iter(lst)
start = list(islice(itlst, 0, n-1))
deq = deque(start, n)
for elt in chain(itlst, start):
deq.append(elt)
yield list(deq)
i=(range(10))
for x in len(i):
print i[:2]
i=i[1:]+[i[1]]
more pythonic than this is impossible
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! :-)