Skip to content Skip to sidebar Skip to footer

Iterate Over All Lists Inside A List Of Varied Lengths

I have a list of lists. It looks something like this: [ [4,7,9,10], [5,14,55,24,121,56, 89,456, 678], [100, 23, 443, 34, 1243,] .... ] I want to iterate such that

Solution 1:

zip_longest is problematic, since any solution would silently drop the fillvalue if it occurs in the inputs (this can be worked around, but it's always going to be a little hacky).

The most general solution is the roundrobin recipe from the itertools module:

from itertools import cycle, islice

defroundrobin(*iterables):
    "roundrobin('ABC', 'D', 'EF') --> A D E B F C"# Recipe credited to George Sakkis
    num_active = len(iterables)
    nexts = cycle(iter(it).__next__ for it in iterables)
    while num_active:
        try:
            fornextin nexts:
                yieldnext()
        except StopIteration:
            # Remove the iterator we just exhausted from the cycle.
            num_active -= 1
            nexts = cycle(islice(nexts, num_active))

For your input, you'd do something like:

mylist = [
    [4,7,9,10],
    [5,14,55,24,121,56, 89,456, 678],
    [100, 23, 443, 34, 1243,]
    ....
]    

print(list(roundrobin(*mylist)))

Solution 2:

You can use itertools.zip_longest() (which is part of the standard library, and is an alternative to the builtin zip(), which truncates its output to the shortest of its arguments), to reorder/rotate the lists, and then use a double list comprehension to flatten that output.

from itertools import zip_longest

inp = [
    [4,7,9,10],
    [5,14,55,24,121,56, 89,456, 678],
    [100, 23, 443, 34, 1243,]
]

output = [
    elem 
    for tup in zip_longest(*inp)   # if we don't provide a fillvalue... for elem in tup                #   ...missing elements are replaced with None...if elem isnotNone#   ...which we can filter out
]
# [4, 5, 100, 7, 14, 23, 9, 55, 443, 10, 24, 34, 121, 1243, 56, 89, 456, 678]

Solution 3:

A simple thing to do would be to just convert the given list into a list of equal sized lists by appending with a known value. Then we can iterate over it and add to result only when the element is not the known value.

res = []
extra_val = '#'
max_len = float('-inf')
for each in l:
    max_len = max(max_len, len(each))

for each in l:
    iflen(each) < max_len:
        n = max_len - len(each)
        extra_list = [extra_val]*n
        each.extend(extra_list)

for i inrange(max_len):
    for j inrange(len(l)):
        if l[j][i] != extra_val:
            res.append(l[j][i])

print(res)

Post a Comment for "Iterate Over All Lists Inside A List Of Varied Lengths"