单行嵌套循环

问题:单行嵌套循环

在转置矩阵的python中编写此函数:

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

最好的信息来源是有关列表理解官方Python教程。列表理解与for循环几乎相同(当然,任何列表理解都可以写为for循环),但它们通常比使用for循环更快。

在教程中查看这个更长的列表理解(该if部分过滤了理解,只有通过if语句的部分才被传递到列表理解的最后一部分(此处(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)]

它与嵌套的for循环完全相同(并且,如本教程所述,请注意for和if的顺序如何相同)。

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

列表理解和for循环之间的主要区别在于for循环的最后部分(您在其中进行操作)始于而不是结束。

关于您的问题:

为了将其用于循环结构,对象必须是哪种类型?

一个可迭代的。可以生成(有限)元素集的任何对象。这些包括任何容器,列表,集合,生成器等。

将i和j分配给object中的元素的顺序是什么?

它们的分配顺序与从每个列表生成的顺序完全相同,就好像它们在嵌套的for循环中一样(对于第一次理解,您将为i获得1个元素,然后将j中的每个值,第2个元素赋给i,然后来自j等的每个值)

可以用不同的for循环结构模拟吗?

是的,上面已经显示了。

可以将此for循环嵌套在相似或不同的for循环结构中吗?看起来如何?

是的,但这不是一个好主意。例如,在此处为您提供字符列表:

[[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

您可能对感兴趣itertools.product,它会从您传递的所有可迭代对象中返回一个可迭代的值元组。也就是说,itertools.product(A, B)产生形式的所有值(a, b),其中a值来自Ab值来自B。例如:

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]

请注意,传递给最终参数的参数itertools.product是“内部” 参数。通常等于itertools.product(a0, a1, ... an)[(i0, i1, ... in) for in in an for in-1 in an-1 ... for i0 in a0]

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

首先,您的第一个代码本身并不使用for循环,而是使用列表推导

  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)

    不过,当然功能必须得到ij本身。

  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

您可以使用zip函数在同一行中使用两个for循环

码:

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

因此,通过使用zip函数,我们可以使用两个for循环,也可以迭代同一行中的两个列表。

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循环时,请记住第一个循环的输出是第二个循环的输入。使用嵌套循环时,循环终止也很重要

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