Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterate over two lists with different lengths

Tags:

python

loops

list

I have 2 lists of numbers that can be different lengths, for example:

list1 = [1, 2, -3, 4, 7]
list2 = [4, -6, 3, -1]

I need to iterate over these with the function:

final_list = []
for index in range(???):
    if list1[index] < 0:
        final_list.insert(0, list1[index])
    elif list1[index] > 0:
        final_list.insert(len(final_list), list1[index])
    if list2[index] < 0:
        final_list.insert(0, list2[index])
    elif list2[index] > 0:
        final_list.insert(len(final_list), list2[index])
return final_list

but can't figure out how to deal with the range as the shorter list will become "out of range" if I use the max length. Any thoughts on how to overcome this or how to change my function?

like image 260
pmit Avatar asked May 16 '17 11:05

pmit


People also ask

How do you iterate over a list length?

You can loop through the list items by using a while loop. Use the len() function to determine the length of the list, then start at 0 and loop your way through the list items by referring to their indexes. Remember to increase the index by 1 after each iteration.

Can you iterate through two lists simultaneously Python?

Use the zip() Function to Iterate Over Two Lists in Python Python zip function enables us to iterate over two or more lists by running until the smaller list gets exhausted. The zip function accepts multiple lists, strings, etc., as input.

Can a for loop be used to iterate over a list?

Using Python for loop to iterate over a list. In this syntax, the for loop statement assigns an individual element of the list to the item variable in each iteration. Inside the body of the loop, you can manipulate each list element individually.


2 Answers

itertools.zip_longest(*iterables, fillvalue=None) will do the job for you:

If the iterables are of uneven length, missing values are filled-in with fillvalue.

For your example lists, this will yield:

>>> import itertools
>>> list1 = [1, 2, -3, 4, 7]
>>> list2 = [4, -6, 3, -1]

>>> for combination in itertools.zip_longest(list1, list2):
    print(combination)

(1, 4)
(2, -6)
(-3, 3)
(4, -1)
(7, None)

If you only want to use as many values as are present in both lists, use the built-in zip():

The iterator stops when the shortest input iterable is exhausted.

>>> for combination in zip(list1, list2):
    print(combination)

(1, 4)
(2, -6)
(-3, 3)
(4, -1)
like image 151
Christian König Avatar answered Oct 04 '22 14:10

Christian König


You can process adjacent items from the lists by using itertools.zip_longest() (itertools.izip_longest() if using Python 2) to produce a sequence of paired items. Pairs will be padded with None for lists of mismatched length.

Then you can simplify the code in the body of the loop by flattening the sequence of paired items and filtering out the None values, and in your case, 0 values. That's what the generator expression below does.

Then it's just a matter of appending or inserting values into final_list if greater or less than zero respectively.

In code:

from itertools import zip_longest

final_list = []
for value in (i for pair in zip_longest(list1, list2) for i in pair if i):
    if value > 0:
        final_list.append(value)
    else:
        final_list.insert(0, value)

print(final_list)
[-1, -3, -6, 1, 4, 2, 3, 4, 7]

Notice that this will filter out any zero values that might be present in the lists. If you want to keep these then modify the generator expression to filter out the None values only:

(i for pair in zip_longest(list1, list2)
    for i in pair if i is not None)

and modify the body of the loop to insert the 0 wherever it should go in final_list.

like image 38
mhawke Avatar answered Oct 04 '22 14:10

mhawke