Iterate consecutive elements in a list in Python such that the last element combines with first
Iterate consecutive elements in a list in Python such that the last element combines with first
I have a list:
L = [1,2,3,4,5,6,7,8]
I want to iterate consecutive elements in the list such that, when it comes to last element i'e 8 it pairs with the first element 1.
The final output I want is:
[1,2],[2,3],[3,4],[4,5],[5,6],[6,7],[7,8],[8,1]
I tried using this way:
for first,second in zip(L, L[1:]):
print([first,second])
But I am getting only this result:
[1,2],[2,3],[3,4],[4,5],[5,6],[6,7],[7,8]
How do I make a pair of last element with first? I have heard about the negative indexing property of a list.
9 Answers
9
You can simply extend the second list in zip()
with a list with only the first item, something like:
zip()
for first, second in zip(L, L[1:] + L[0:1]): # or simply zip(L, L[1:] + L[:1])
print([first, second])
L[0:1] == L[0] == L[:1]
L[0:1] == L[0] # returns False
, L[0] gives 1
, L[0:1] gives [1]
(a list)– Kamil
Aug 22 at 12:54
L[0:1] == L[0] # returns False
1
[1]
ahh, you're right! my bad!
– aydow
Aug 22 at 12:56
You can use cycle
to cycle the lists (in combination with islice
to skip the first element):
cycle
islice
from itertools import cycle, islice
L = [1,2,3,4,5,6,7,8]
rest_L_cycled = islice(cycle(L), 1, None)
items = zip(L, rest_L_cycled)
print(list(items))
This is easily extensible. Note that it relies on the fact that zip
halts on the shorter list (the second argument is an infinite cycle). It also does everything lazily and does not create any intermediate list (well, except for the print
ed list) :-)
zip
print
ok. you beat me to an
itertools
version... +1!– hiro protagonist
Aug 22 at 12:33
itertools
You can also iterate through the indexes of L
, and for the index of the second item of the output tuples, simply use the remainder of the length of L
:
L
L
[(L[i], L[(i + 1) % len(L)]) for i in range(len(L))]
@blshing I think it the simplest solution.
– kantal
Aug 26 at 17:59
You can simply concatenate the list resulting from zip(L, L[1:]) with the pair formed by the last element L[-1] and first one L[0] and iterate over the result
for first,second in zip(L, L[1:]) + [(L[-1],L[0])]:
print ([first,second])
It gives the desired outcome.
It's not a one-liner, but:
>>> L = [1,2,3,4,5,6,7,8]
>>> z = list(zip(L[:-1], L[1:]))
>>> z.append((L[-1], L[0]))
>>> z
[(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 1)]
You can just append the front element(s) to the back.
for first,second in zip(L, L[1:] + L[:1]):
print([first,second])
for i in range(len(L)):
first = L[i]
second = L[(i+1) % len(L)]
You can simply use itertools.zip_longest
with a fillvalue
of the first item.
itertools.zip_longest
fillvalue
from itertools import zip_longest
list(map(tuple, zip_longest(L, L[1:], fillvalue=L[0]))
This is a version (over-)using itertools
:
itertools
from itertools import islice, cycle
L = [1,2,3,4,5,6,7,8]
for a, b in zip(L, islice(cycle(L), 1, None)):
print(a, b)
The idea is to cycle
over the second argument - that way zip
runs until L
itself is exhausted. This does not create any new lists.
cycle
zip
L
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
L[0:1] == L[0] == L[:1]
– aydow
Aug 22 at 12:53