Reputation: 93
I'm looking for the most elegant/short/pythonic way to iterate through two uneven lists simultaneously. If the shorter list ends at some point, it should start to iterate from the beginning.
So far, I managed to do it with the while
, which I consider as ugly, and too long (from various reasons I need as short code as possible).
list1 = ["a", "b", "c"]
list2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
i1 = 0
i2 = 0
while True:
if i2 == len(list2):
break
if i1 == len(list1):
i1 = 0
print(list1[i1], list2[i2])
i1 += 1
i2 += 1
The expected result should look like this. I'm achieving it with while loop (the code above). But I need to have as short code as possible:
a 1
b 2
c 3
a 4
b 5
c 6
a 7
b 8
c 9
a 10
Upvotes: 3
Views: 155
Reputation: 3537
Use itertools
:
import itertools
list1 = ["a","b","c"]
list2 = [1,2,3,4,5,6,7,8,9,10]
print(list(itertools.cycle(list1), list2))
Upvotes: 0
Reputation: 114230
If you don't know the sizes of your lists, use sorted
to get it:
list1 = ["a", "b", "c"]
list2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
shorter, longer = sorted([list1, list2], key=len)
Now you can itertools.cycle
the shorter one, and zip
:
for item1, item2 in zip(cycle(shorter), longer):
...
This won't necessarily print your items in the order that you may have originally wanted (list1
on the left, list2
on the right). To fix that, you can just compute the longer list by hand:
iter1, iter2 = cycle(list1), list2 if len(list1) < len(list2) else list1, cycle(list2)
for item1, item2 in zip(iter1, iter2):
...
You could make it a one-liner with
for item1, item2 in zip(*(cycle(list1), list2 if len(list1) < len(list2) else list1, cycle(list2))):
...
Upvotes: 1
Reputation: 2298
I've got something that is a bit cleaner than what you've got and doesn't require you know in advance which is larger. No idea if this is the most elegant/short/pythonic way to do things but here goes:
list1 = ["a","b","c"]
list2 = [1,2,3,4,5,6,7,8,9,10]
length1 = len(list1)
length2 = len(list2)
for i in range(max(length1,length2)):
print(list1[i%length1],list2[i%length2])
prints the following:
a 1
b 2
c 3
a 4
b 5
c 6
a 7
b 8
c 9
a 10
Upvotes: 4
Reputation: 61910
You could do:
list1 = ["a", "b", "c"]
list2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for i, e in enumerate(list2):
print(list1[i % len(list1)], e)
Output
a 1
b 2
c 3
a 4
b 5
c 6
a 7
b 8
c 9
a 10
Upvotes: 4
Reputation: 140168
zip
both lists, feeding the shortest one to itertools.cycle
so it repeats indefinitely (until list2
ends):
import itertools
list1 = ["a","b","c"]
list2 = [1,2,3,4,5,6,7,8,9,10]
for a,b in zip(itertools.cycle(list1),list2):
print(a,b)
prints:
a 1
b 2
c 3
a 4
b 5
c 6
a 7
b 8
c 9
a 10
(of course don't use itertools.zip_longest
as cycle
never ends, which would create an infinite loop)
Upvotes: 9