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]
– aydow
Aug 22 at 12:53



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 printed 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.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)