2014-10-30 120 views
2

我遇到了一种情况,我需要实现一个带有多个循环控制变量的for循环。基本上这就是我要做的Python中的多个循环控制变量for循环

的Java:

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)构造?

+0

什么是用例?也就是说,这些值实际上会做什么循环? – BrenBarn 2014-10-30 04:45:50

+0

这有什么关系?让我们来说说'print i * j'' – user949110 2014-10-30 04:47:26

+0

是的,因为通常你可以遍历循环中试图使用的实际项目,而不是数字索引。 – BrenBarn 2014-10-30 04:53:19

回答

4

对于您的具体示例,它看起来并不像在循环定义本身中真的需要单独的变量。你可以只遍历我的价值观和做N-1构成的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 

这需要我从第一范围(0到n-1)和从j第二个(n到1)。 zip通过分组配对您提供的可迭代元素来创建新的迭代。

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

for (i=iterable.getNextValue(); iterable.isNotEmpty(); i=iterable.getNextValue()) 

你不能有环路初始化从循环更新不同,你不能有那些是任何除了“获取下一个值”之外的操作,并且您不能将结束条件设置为“是可迭代耗尽”之外的其他任何操作。如果你想做这样的事情,你必须在循环内自己做(例如,通过分配一个次要的“循环变量”在我的例子中,或者通过检查自定义循环退出条件和突破),或者将其构建到您正在迭代的“源”中。

+0

对,这确实会起作用。但来自Java背景我很惊讶,没有python结构的multi-var for-loop。我会再等一会儿,看看在接受你之前是否有更好的答案 – user949110 2014-10-30 04:59:47

+0

@ user949110:我在我的答案中加了一点,说明如何在'for'循环中指定这两个循环,尽管我认为这种方式在这方面的可读性较差案件。 – BrenBarn 2014-10-30 05:02:02

+0

@BrenBarn将'列举'也工作?如果是,那么你能否将它添加到你的答案呢? – 2014-10-30 05:03:53

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] 
+1

这又是嵌套循环,这不是他想要的。 – BrenBarn 2014-10-30 04:57:16

0

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

下面是一些标准的Python技巧:

嵌套循环

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

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

拉链

多个迭代器可以使用zip()它会创建一个可同时从几个迭代中的每个迭代产生一个值的可迭代对象。您可以使用multple分配for循环中抢个出了拉链的

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 

拉链就会停止第一部件已耗尽:

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

拉链也使用发电机:

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

对于更复杂的迭代,在012中有很多很棒的工具这对于获取多个迭代器的所有产品或排列组合是特别好的。这是值得检查,但我认为它比你需要的更多