125

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

在这个过程中,我意识到我并不完全理解单行嵌套 for 循环是如何执行的。请通过回答以下问题帮助我理解:

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

鉴于,

[ function(i,j) for i,j in object ]
  1. 对象必须是什么类型才能使用这个 for 循环结构?
  2. 将 i 和 j 分配给 object 中的元素的顺序是什么?
  3. 可以用不同的for循环结构来模拟吗?
  4. 这个 for 循环可以嵌套在类似或不同结构的 for 循环中吗?它看起来如何?

其他信息也值得赞赏。

4

5 回答 5

206

最好的信息来源是关于列表推导的官方 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 循环的最后部分(你在其中做某事的地方)出现在开头而不是结尾。

关于你的问题:

对象必须是什么类型才能使用这个 for 循环结构?

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

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

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

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

是的,上面已经显示了。

这个 for 循环可以嵌套在类似或不同结构的 for 循环中吗?它看起来如何?

当然可以,但这不是一个好主意。例如,这里给你一个字符列表:

[[ch for ch in word] for word in ("apple", "banana", "pear", "the", "hello")]
于 2013-06-09T05:26:17.097 回答
40

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

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]

于 2013-06-09T10:13:00.490 回答
4

首先,您的第一个代码本身不使用 for 循环,而是使用list comprehension

  1. 相当于

    对于范围内的 j(0,宽度):对于范围内的 i(0,高度):m[i][j]

  2. 几乎相同的方式,它通常像 for 循环一样嵌套,从右到左。但是列表理解语法更复杂。

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


  1. 产生恰好产生两个对象的可迭代对象的任何可迭代对象(什么是满嘴 - 即[(1,2),'ab']有效)

  2. 对象在迭代时产生的顺序。i去第一个产量,j第二个。

  3. 是的,但没有那么漂亮。我相信它在功能上等同于:

    l = 列表()
    对于对象中的 i,j:
        l.append(函数(i,j))
    

    甚至更好地使用map

    map(function, object)
    

    但当然功能必须得到i,j本身。

  4. 这不是和3一样的问题吗?

于 2013-06-09T05:30:26.863 回答
1

您可以使用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 循环,或者我们可以在同一行中迭代两个列表。

于 2020-04-27T06:37:25.133 回答
-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
于 2019-09-17T06:08:37.380 回答