单行嵌套循环

时间:2013-06-09 05:08:32

标签: python loops for-loop nested nested-loops

在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. 等于unnested for loop会等于什么?
  4. 鉴于,

    [ function(i,j) for i,j in object ]
    
    1. 为了将这个用于循环结构,必须使用什么类型的对象?
    2. i和j分配给对象中元素的顺序是什么?
    3. 可以通过不同的for循环结构进行模拟吗?
    4. 这个for循环可以嵌套到类似或不同的循环结构吗?它看起来怎么样?
    5. 其他信息也很受欢迎。

5 个答案:

答案 0 :(得分:130)

最好的信息来源是official Python tutorial on list comprehensions。列表推导与循环几乎相同(当然任何列表理解都可以写成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循环的最后部分(你做某事的地方)来自开头而不是结尾。

关于你的问题:

  

为了将这个用于循环结构,必须使用哪种类型?

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

  

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

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

  

可以通过不同的for循环结构进行模拟吗?

是的,已在上面显示。

  

这个for循环可以用循环的相似或不同结构嵌套吗?它看起来怎么样?

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

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

答案 1 :(得分:25)

您可能对itertools.product感兴趣,它会从您传递的所有迭代中返回一个可迭代的值元组。也就是说,itertools.product(A, B)会生成(a, b)形式的所有值,其中a值来自A,而b值来自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]

答案 2 :(得分:2)

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

  1. 等同于

    表示范围内的j(0,宽度):     for i in range(0,height):         M [i] [j]

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

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


    1. 任何可迭代的对象产生可以产生两个对象的可迭代对象(多么令人满意 - 即[(1,2),'ab']有效)

    2. 迭代时对象产生的顺序。 i转到第一个收益,j第二个。

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

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

      甚至更好地使用map

      map(function, object)
      

      但当然功能必须得到ij本身。

    4. 这不是与3相同的问题吗?

答案 3 :(得分:2)

您可以使用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循环,也可以迭代同一行中的两个列表。

答案 4 :(得分:-1)

下面的代码提供了嵌套循环的最佳示例,同时使用两个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