Python for循环中的多个循环控制变量

时间:2014-10-30 04:45:13

标签: python for-loop

我遇到过需要使用多个循环控制变量实现for循环的情况。基本上这就是我想要做的事情

爪哇:

for (int i=0,j=n; i<n,j>=0; i++, j--)     
    do my stuff

我如何在Python中执行此操作?

for i in range(0,n), j in range(n-1,-1,-1): 
    do my stuff

但这不起作用。这里的语法是什么?另外,用例是否有更优雅(pythonic)的构造?

3 个答案:

答案 0 :(得分:4)

对于您的具体示例,看起来您在循环定义本身中确实需要单独的变量。您可以通过执行n-i来迭代i值并构造j值:

for i in range(0, n):
     j = n-i
     # do stuff

通常,如果for语句相互依赖,则不能在for语句中指定多个值。相反,使用for来迭代一些“基础”值或其他值可以从中派生的值。

可以for i, j in zip(range(0, n), range(n, 0, -1)): # do stuff 循环中指定多个值,但它们必须从单个可迭代中提取:

zip

这使得i从第一个范围(0到n-1)和j从第二个范围(n到1)。 for通过按顺序配对您给它的迭代元素来创建一个新的可迭代。

要记住的是,Python for循环不像Java / C中的循环,它具有初始化/检查结束条件/更新结构,可重复修改某些持久循环索引变量。 Python foreach循环迭代“源”可迭代提供的值的“流”,一次从源中获取一个值。 (这类似于 for (i=iterable.getNextValue(); iterable.isNotEmpty(); i=iterable.getNextValue()) - 在其他一些语言中的类型构造。)无论你想要迭代什么,你需要在开始循环之前将它变成一个迭代。换句话说,每个Python for循环可以被认为大致类似于:

{{1}}

你不能让循环初始化与循环更新不同,并且除了“获取下一个值”之外你不能有任何操作,并且你不能让结束条件不是除了“是可迭代的”。如果你想做那样的事情,你必须在循环中自己做(例如,通过在我的例子中指定一个辅助“循环变量”,或者通过检查自定义循环退出条件和爆发),或者将它构建到你正在迭代的“源”中。

答案 1 :(得分:0)

您可以使用多个循环控制变量创建list comprehension

>>> n = 10
>>> stuff = [i*j for i in range(n) for j in range(n-1,-1,-1)]
>>> stuff
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 18, 16, 14, 12, 10, 8, 6, 4, 2, 0, 27, 24, 21, 18, 15, 12, 9, 6, 3, 0, 36, 32, 28, 24, 20, 16, 12, 8, 4, 0, 45, 40, 35, 30, 25, 20, 15, 10, 5, 0, 54, 48, 42, 36, 30, 24, 18, 12, 6, 0, 63, 56, 49, 42, 35, 28, 21, 14, 7, 0, 72, 64, 56, 48, 40, 32, 24, 16, 8, 0, 81, 72, 63, 54, 45, 36, 27, 18, 9, 0]

答案 2 :(得分:0)

很大程度上取决于你想要的迭代器。这里有几个选择。它们的共同点是for... in...将遍历列表,元组和其他任何支持迭代的东西。因此,您可以遍历已知值的列表或generator,它会生成任意值的一系列值。 for... in...无论如何都是一样的。

这里有一些标准的python技巧:

嵌套循环

for i in range(10):
    for j in range (10):
        print i, j

这很简单明了,但对于复杂的迭代,它可能会得到非常深的嵌套。这里rangegenerator,这意味着它会在一个系列上产生一个迭代(在这种情况下,10个数字 - 但它可以是任意值的任意流)。

拉链

对于多个迭代器,您可以使用zip()创建一个可迭代对象,该对象同时从多个可迭代中的每个迭代中生成一个值。您可以在for循环中使用多重赋值来从zip中抓取部分

a = [1,2,3,4]
b = ['a','b','c','d']
for  number, letter in zip (a, b):
    print letter, ":", number
# a : 1
# b : 2
# c : 3
# d : 4
当第一个成员用尽时,

zip将停止:

a = [1,2]
b = ['a','b','c','d']
for  number, letter in zip (a, b):
    print letter, ":", number
# a : 1
# b : 2

zip也使用生成器:

test = zip (range(10), range(10,20))
for item in test: print item
#(0, 10)
#(1, 11)
#(2, 12)
#(3, 13)
#(4, 14)
#(5, 15)
#(6, 16)
#(7, 17)
#(8, 18)
#(9, 19)

itertools

对于更复杂的迭代,itertools module中有很多很棒的工具。这对于获取所有产品或多个迭代器的排列等特别好。值得一试,但我认为这比您需要的更多