2014-10-30 210 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中有很多很棒的工具這對於獲取多個迭代器的所有產品或排列組合是特別好的。這是值得檢查,但我認爲它比你需要的更多