Home > Net >  List comprehension as multi-line
List comprehension as multi-line

Time:05-26

I am learning Python and trying to understand how to write the list comprehension in the following code as multi-line code. I am just lost as I haven't seen the variable called inside its own comprehension before.

list_of_lists = [['a','b','c','d'],[1,2,3]]

result = [[]]
  for l in list_of_lists:
    result = [x [y] for x in result for y in l]

CodePudding user response:

Your code is roughly equivalent to the following code. Note the order of the for-loop on result and the for-loop on l.

list_of_lists = [['a','b','c','d'],[1,2,3]]

result = [[]]
for l in list_of_lists:
    new_result = []
    for x in result:
        for y in l:
            new_product = x   [y]
            new_result.append(new_product)
    result = new_result

You can read more about list comprehensions in the Python documentation. It has another example of double use of for in one list comprehension.

For example, this listcomp combines the elements of two lists if they are not equal:

>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

and it’s equivalent to:

>>> combs = []
>>> for x in [1,2,3]:
...     for y in [3,1,4]:
...         if x != y:
...             combs.append((x, y))
...
>>> combs
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

CodePudding user response:

The code is ugly, unpythonic and very inefficient. It is unclear what its goal is. You should not try to imitate the code.

list_of_lists = [['a','b','c','d'],[1,2,3]]

result = [[]]
for l in list_of_lists:
    result = [x [y] for x in result for y in l]

print(result)

The above yields:

[['a', 1], ['a', 2], ['a', 3], ['b', 1], ['b', 2], ['b', 3], ['c', 1], ['c', 2], ['c', 3], ['d', 1], ['d', 2], ['d', 3]]

Basically, it takes two big loops, each loop loops through a sublist inside the list of lists.

The first loop has four iterations, it creates a list containing an element in the first sublist for each element inside the first sublist, and put all of them inside result

The second big loop contains 3 subloops, each loop has four iterations.

The first level loop loops through the numbers, the second level loop loops through the sublists inside result, then adds the number to the sublist, collects the sublists and reassigns the collection to result.

I won't rewrite the code into nested for loops, it might lead you astray.

But if your goal is to generate something like what the code generates, you can do this:

letters = ['a', 'b', 'c', 'd']
numbers = [1, 2, 3]

result = []

for l in letters:
    for n in numbers:
        result.append([l, n])

You can write it as a list comprehension:

result = [[l, n] for l in letters for n in numbers]

The result is the Cartesian product of the two lists, Python has a very efficient function in its standard library that does exactly this:

from itertools import product

list(product(letters, numbers))
[('a', 1), ('a', 2), ('a', 3), ('b', 1), ('b', 2), ('b', 3), ('c', 1), ('c', 2), ('c', 3), ('d', 1), ('d', 2), ('d', 3)]
  • Related