Explanation of how nested list comprehension works?

前端 未结 8 1237
情书的邮戳
情书的邮戳 2020-11-22 02:06

I have no problem for understanding this:

a = [1,2,3,4]
b = [x for x in a]

I thought that was all, but then I found this snippet:



        
相关标签:
8条回答
  • 2020-11-22 02:27

    if a = [[1,2],[3,4],[5,6]], then if we unroll that list comp, we get:

          +----------------a------------------+ 
          | +--xs---+ , +--xs---+ , +--xs---+ | for xs in a
          | | x , x |   | x , x |   | x , x | | for x in xs
    a  =  [ [ 1 , 2 ] , [ 3 , 4 ] , [ 5 , 6 ] ]
    b  =  [ x for xs in a for x in xs ] == [1,2,3,4,5,6] #a list of just the "x"s
    
    0 讨论(0)
  • 2020-11-22 02:35

    b = [x for xs in a for x in xs] is similar to following nested loop.

    b = []
    for xs in a:
       for x in xs:
           b.append(x)
    
    0 讨论(0)
  • 2020-11-22 02:35

    This is an example of a nested comprehension. Think of a = [[1,2],[3,4],[5,6]] as a 3 by 2 matrix (matrix= [[1,2],[3,4],[5,6]]).

           ______
    row 1 |1 | 2 |
           ______
    row 2 |3 | 4 |
           ______
    row 3 |5 | 6 |
           ______
    

    The list comprehension you see is another way to get all the elements from this matrix into a list.

    I will try to explain this using different variables which will hopefully make more sense.

    b = [element for row in matrix for element in row]
    

    The first for loop iterates over the rows inside the matrix ie [1,2],[3,4],[5,6]. The second for loop iterates over each element in the list of 2 elements.

    I have written a small article on List Comprehension on my website http://programmathics.com/programming/python/python-list-comprehension-tutorial/ which actually covered a very similar scenario to this question. I also give some other examples and explanations of python list comprehension.

    Disclaimer: I am the creator of that website.

    0 讨论(0)
  • 2020-11-22 02:35

    Here is how I best remember it: (pseudocode, but has this type of pattern)

    [(x,y,z) (loop 1) (loop 2) (loop 3)]
    

    where the right most loop (loop 3) is the inner most loop.

    [(x,y,z)    for x in range(3)    for y in range(3)    for z in range(3)]
    

    has the structure as:

    for x in range(3):
        for y in range(3):
            for z in range(3):
                print((x,y,z))
    

    Edit I wanted to add another pattern:

    [(result) (loop 1) (loop 2) (loop 3) (condition)]
    

    Ex:

    [(x,y,z)    for x in range(3)    for y in range(3)    for z in range(3)    if x == y == z]
    

    Has this type of structure:

    for x in range(3):
        for y in range(3):
            for z in range(3):
                if x == y == z:
                    print((x,y,z))
    
    
    
    
    0 讨论(0)
  • 2020-11-22 02:39

    Ah, the incomprehensible "nested" comprehensions. Loops unroll in the same order as in the comprehension.

    [leaf for branch in tree for leaf in branch]
    

    It helps to think of it like this.

    for branch in tree:
        for leaf in branch:
            yield leaf
    

    The PEP202 asserts this syntax with "the last index varying fastest" is "the Right One", notably without an explanation of why.

    0 讨论(0)
  • 2020-11-22 02:44

    Yes, you can nest for loops INSIDE of a list comprehension. You can even nest if statements in there.

    dice_rolls = []
    for roll1 in range(1,7):
        for roll2 in range(1,7):
            for roll3 in range(1,7):
                dice_rolls.append((roll1, roll2, roll3))
    
    # becomes
    
    dice_rolls = [(roll1, roll2, roll3) for roll1 in range(1, 7) for roll2 in range(1, 7) 
                  for roll3 in range(1, 7)]
    

    I wrote a short article on medium explaining list comprehensions and some other cool things you can do with python, you should have a look if you're interested : )

    0 讨论(0)
提交回复
热议问题