How can I loop through a list in a nested list using python list comprehension?

Question:

I’m trying to practice using list comprehensions in Python.

I set myself the task of making a list based off domino pieces that have a 5 on them. That is, the result should be:

[[5, 0], [5, 1], [5, 2], [5, 3], [5, 4], [5, 5], [5, 6]]

I’m following a course, but the examples so far only show how to create these types of nested lists with ascending numbers using ranges, like [[1,2,3], [1,2,3]].

I tried this code:

x = [val for val in range(0,7)]

Fives = [[5,x] for pieces in range(0,7)] 
print(Fives)

But I get a wrong result:

[[5, [0, 1, 2, 3, 4, 5, 6]], [5, [0, 1, 2, 3, 4, 5, 6]], [5, [0, 1, 2, 3, 4, 5, 6]], [5, [0, 1, 2, 3, 4, 5, 6]], [5, [0, 1, 2, 3, 4, 5, 6]], [5, [0, 1, 2, 3, 4, 5, 6]], [5, [0, 1, 2, 3, 4, 5, 6]]]

What is wrong, and how do I fix it?

Asked By: superavd88

||

Answers:

You’re dangerously close to an XY Problem here!

Switching approaches, in order to create all the possible domino pieces, instead you can use itertools.permutations()

>>> list(permutations(range(6+1), 2))
[(0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (1, 0), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 0), (2, 1), (2, 3), (2, 4), (2, 5), (2, 6), (3, 0), (3, 1), (3, 2), (3, 4), (3, 5), (3, 6), (4, 0), (4, 1), (4, 2), (4, 3), (4, 5), (4, 6), (5, 0), (5, 1), (5, 2), (5, 3), (5, 4), (5, 6), (6, 0), (6, 1), (6, 2), (6, 3), (6, 4), (6, 5)]

However, if instead of generating the collection directly, you must iterate through an inner list, instead iterate over it by directly using a form like for value in collection: (as all common collections are iterable – docs on iterator and sequence types)

values = list(range(7))  # 0,1,2,3,4,5,6
results = []
for val_upper in range(7):    # or your original list as they're the same!
    for val_lower in values:  # iterate over collection, getting each in turn
        results.append([val_upper, val_lower])

or when the upper (leftmost?) value is always 5 (perhaps what you really expected)

>>> values = list(range(6+1))
>>> [[5, x] for x in values]  # iterates over values
[[5, 0], [5, 1], [5, 2], [5, 3], [5, 4], [5, 5], [5, 6]]

Finally, if you have a small collection (as is the case here) and only wanted values that start with 5, you could comprehend your collection back filtering it as you go
..in this small case, it’s not particularly elegant, but it’s far more useful when generating a collection which isn’t mathematically perfect or has specialized filtering requirements

>>> list(domino for domino in permutations(range(6+1), 2) if domino[0] == 5)
[(5, 0), (5, 1), (5, 2), (5, 3), (5, 4), (5, 6)]
Answered By: ti7
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.