Single Line Nested For Loops

290,766

Solution 1

The best source of information is the official Python tutorial on list comprehensions. List comprehensions are nearly the same as for loops (certainly any list comprehension can be written as a for-loop) but they are often faster than using a for loop.

Look at this longer list comprehension from the tutorial (the if part filters the comprehension, only parts that pass the if statement are passed into the final part of the list comprehension (here (x,y)):

>>> [(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)]

It's exactly the same as this nested for loop (and, as the tutorial says, note how the order of for and if are the same).

>>> 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)]

The major difference between a list comprehension and a for loop is that the final part of the for loop (where you do something) comes at the beginning rather than at the end.

On to your questions:

What type must object be in order to use this for loop structure?

An iterable. Any object that can generate a (finite) set of elements. These include any container, lists, sets, generators, etc.

What is the order in which i and j are assigned to elements in object?

They are assigned in exactly the same order as they are generated from each list, as if they were in a nested for loop (for your first comprehension you'd get 1 element for i, then every value from j, 2nd element into i, then every value from j, etc.)

Can it be simulated by a different for loop structure?

Yes, already shown above.

Can this for loop be nested with a similar or different structure for loop? And how would it look?

Sure, but it's not a great idea. Here, for example, gives you a list of lists of characters:

[[ch for ch in word] for word in ("apple", "banana", "pear", "the", "hello")]

Solution 2

You might be interested in itertools.product, which returns an iterable yielding tuples of values from all the iterables you pass it. That is, itertools.product(A, B) yields all values of the form (a, b), where the a values come from A and the b values come from B. For example:

import itertools

A = [50, 60, 70]
B = [0.1, 0.2, 0.3, 0.4]

print [a + b for a, b in itertools.product(A, B)]

This prints:

[50.1, 50.2, 50.3, 50.4, 60.1, 60.2, 60.3, 60.4, 70.1, 70.2, 70.3, 70.4]

Notice how the final argument passed to itertools.product is the "inner" one. Generally, itertools.product(a0, a1, ... an) is equal to [(i0, i1, ... in) for in in an for in-1 in an-1 ... for i0 in a0]

Solution 3

First of all, your first code doesn't use a for loop per se, but a list comprehension.

  1. Would be equivalent to

    for j in range(0, width): for i in range(0, height): m[i][j]

  2. Much the same way, it generally nests like for loops, right to left. But list comprehension syntax is more complex.

  3. I'm not sure what this question is asking


  1. Any iterable object that yields iterable objects that yield exactly two objects (what a mouthful - i.e [(1,2),'ab'] would be valid )

  2. The order in which the object yields upon iteration. i goes to the first yield, j the second.

  3. Yes, but not as pretty. I believe it is functionally equivalent to:

    l = list()
    for i,j in object:
        l.append(function(i,j))
    

    or even better use map:

    map(function, object)
    

    But of course function would have to get i, j itself.

  4. Isn't this the same question as 3?

Solution 4

You can use two for loops in same line by using zip function

Code:

list1 = ['Abbas', 'Ali', 'Usman']
list2 = ['Kamran', 'Asgar', 'Hamza', 'Umer']
list3 = []
for i,j in zip(list1,list2):
    list3.append(i)
    list3.append(j)
print(list3)

Output:

['Abbas', 'Kamran', 'Ali', 'Asgar', 'Usman', 'Hamza']

So, by using zip function, we can use two for loops or we can iterate two lists in same row.

Share:
290,766
Asher Garland
Author by

Asher Garland

Software engineer at Microsoft since 2014. Currently working on the Azure Portal. Specialize in Front-end architecture, big data analysis, and build & deployment pipelines.

Updated on May 02, 2020

Comments

  • Asher Garland
    Asher Garland about 4 years

    Wrote this function in python that transposes a matrix:

    def transpose(m):
        height = len(m)
        width = len(m[0])
        return [ [ m[i][j] for i in range(0, height) ] for j in range(0, width) ]
    

    In the process I realized I don't fully understand how single line nested for loops execute. Please help me understand by answering the following questions:

    1. What is the order in which this for loop executes?
    2. If I had a triple nested for loop, what order would it execute?
    3. What would be equal the equal unnested for loop?

    Given,

    [ function(i,j) for i,j in object ]
    
    1. What type must object be in order to use this for loop structure?
    2. What is the order in which i and j are assigned to elements in object?
    3. Can it be simulated by a different for loop structure?
    4. Can this for loop be nested with a similar or different structure for loop? And how would it look?

    Additional information is appreciated as well.

  • Thomas
    Thomas over 10 years
    I wonder what guided their choice of ordering in the double nesting. I find the other way more natural (for y then for x in your example). I just realize that after 3 years of doing python (not extensively but still...) and of using those kinds of loops !!
  • Pyjong
    Pyjong about 4 years
    @Thomas I also find the other way more intuitive. The choice I believe was purely convenience. Doing it the more intuitive way would mean having to deal with unresolved symbols until it would find them later in the statement. Try parsing for each banana.peel in each banana for each city.bananastore in each city on paper. Not as easy. The other way around though, nice and easy.
  • JackofSpades
    JackofSpades almost 3 years
    Guido, the creator of python, discourages the use of map so much that he considered removing it from python
  • Beki
    Beki over 2 years
    @JackofSpades Nah, it will not be deleted.