0

I'd like to get the product of two lists. I can do this using itertools.product:

from itertools import product

for i in product([1, 2], ['a', 'b']):
    print(i, end='\t')

Gives:

(1, 'a')    (1, 'b')    (2, 'a')    (2, 'b')

The problem is that one of the two lists could be empty. I just need to iterate over the non-empty list as a normal for loop in this case. Something like:

for i in something([1, 2], []):
    print(i, end='\t')

To give:

1    2

The code works fine if I handle the exception at the beginning with many if statements that checks for the lengths of the lists, and with the same code for every combination (list1 is empty, list2 is empty, none are empty), but this way I just wrote the same code 3 times:

from itertools import product

if not list1:
    for i in list2:
        print(i, end='\t')

elif not list2:
    for i in list1:
        print(i, end='\t')

else:    
    for i in product(list1, list2):
        print(i, end='\t')

Is there a more elegant way to do so?

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
Federicofkt
  • 149
  • 6
  • cant you just loop over a tuple? `for i in (lst, lst2):` – The.B Apr 01 '21 at 09:18
  • @Tomerikoo that doesn't solve the " In the second case I need all of the combinations, like a nested for loop", sice the zip_longest prints all the elements of the longer list, but it doesn't combine them with the elements in the shorter. It just mark them as "None" – Federicofkt Apr 01 '21 at 09:39
  • @The.B I need to access both elements since they are columns in dataframe which I need to select with a .loc separately – Federicofkt Apr 01 '21 at 09:42
  • @Tomerikoo I think that it's pretty clear, but anyway: `list1 = [1,2,3,4] list2 = ["a", "b"] out = 1 a, 1 b, 2 a, 2 b, etc` Instead if one list is empty: ` list1 = [] list2 = ["a", "b"] out = "a", "b" ` – Federicofkt Apr 01 '21 at 09:44
  • Checked for product, I think it doesn't work if one list is empty. If they are the same lenght I just need the combination like a nested loop – Federicofkt Apr 01 '21 at 09:52
  • "The problem is that one of the two lists could be empty. I just need to iterate over the non-empty list as a normal for loop in this case." This design doesn't make any sense. `Special cases aren't special enough`. That said, I'm unmarking the duplicate because that's clearly not the same question - iterating in parallel won't help here. – Karl Knechtel Apr 01 '21 at 10:17
  • Anyway, one way to avoid some of the repetition with this code (just please consider using a different sentinel value, perhaps `None`) is to determine what you're iterating over first, and then unconditionally do the iteration over that thing. But beyond that the question doesn't really make sense; if you want things to work in different ways conditionally, you're going to need to do some kind of work to test the condition. – Karl Knechtel Apr 01 '21 at 10:18
  • Well, it closed with a duplicate link, which is no good. Apparently my reopening cleared the other close votes too. :/ – Karl Knechtel Apr 01 '21 at 10:20
  • @Federicofkt `list(itertools.product(lst1, lst2 if len(lst2) > 0 else " "))` this will work if your first list is always bigger than the second. but you can put it in a if statement to check wich `list` have the bigger length. – The.B Apr 01 '21 at 12:28

1 Answers1

2

I would suggest you the following approach:

seq = product(list1, list2) if (list1 and list2) else (list1 or list2)

for item in seq:
    print(item, end='\t')

You can read about Logical operators in Python to understand why the use of and and or works.

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
zanuda
  • 176
  • 1
  • 6