# 单行嵌套循环

## 问题：单行嵌套循环

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

1. 此for循环执行的顺序是什么？
2. 如果我有一个三重嵌套的for循环，它将执行什么顺序？
3. 等于未嵌套for循环等于什么？

``[ function(i,j) for i,j in object ]``
1. 为了将其用于循环结构，对象必须是哪种类型？
2. 将i和j分配给object中的元素的顺序是什么？
3. 可以用不同的for循环结构模拟吗？
4. 可以将此for循环嵌套在相似或不同的for循环结构中吗？看起来如何？

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.

## 回答 0

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

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

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

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

## 回答 1

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

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

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

## 回答 2

1. 相当于

对于范围（0，宽度）中的j：对于范围（0，高度）中的i：m [i] [j]

2. 大致相同，它通常像for循环一样从右到左嵌套。但是列表理解语法更复杂。

3. 我不确定这个问题在问什么

1. 产生可迭代对象且恰好产生两个对象的任何可迭代对象（实际上`[(1,2),'ab']`是有效的）

2. 对象在迭代时产生的顺序。`i`转到第一个Yield，`j`第二个。

3. 是的，但是不那么漂亮。我相信它在功能上等同于：

```l = list（）
对于对象中的i，j：
l.append（function（i，j））
```

甚至更好地使用map

``map(function, object)``

不过，当然功能必须得到`i``j`本身。

4. 这不是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?

## 回答 3

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

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

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.

## 回答 4

``````for x in range(1, 10, 1):
for y in range(1,x):
print y,
print
OutPut :
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
1 2 3 4 5 6
1 2 3 4 5 6 7
1 2 3 4 5 6 7 8``````

Below code for best examples for nested loops, while using two for loops please remember the output of the first loop is input for the second loop. Loop termination also important while using the nested loops

``````for x in range(1, 10, 1):
for y in range(1,x):
print y,
print
OutPut :
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
1 2 3 4 5 6
1 2 3 4 5 6 7
1 2 3 4 5 6 7 8
``````