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.

You can simply extend the second list in zip() with a list with only the first item, something like:

for first, second in zip(L, L[1:] + L[0:1]): # or simply zip(L, L[1:] + L[:1])
print([first, second])


You can use cycle to cycle the lists (in combination with islice to skip the first element):

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 printed list) :-)

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[i], L[(i + 1) % len(L)]) for i in range(len(L))]


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.

from itertools import zip_longest
list(map(tuple, zip_longest(L, L[1:], fillvalue=L[0]))


This is a version (over-)using 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.

Comments

Popular posts from this blog

Meaning of `{}` for return expression

Get current scroll position of ScrollView in React Native

flutter websocket connection issue