2013-05-05 54 views
3

有人能告訴我Python的for循環是如何實現的嗎?我問這個的原因是因爲我得到不同的行爲在以下兩個for循環,當我想到相同的行爲(假設cases只是一組元素):用於循環實現的Python

第一個for循環:

for case in cases: 
    blah 

第二個for循環:

for i in range(len(cases)): 
    case = cases[i] 
    blah 

我跑我的代碼在多線程環境。

基本上,我想知道是否Python的for循環遍歷一個集合(如在第一個for循環)只是第二個快速簡單的方法。當我們使用python for循環時究竟發生了什麼,並且是否有任何潛在的優化/實現可能導致我觀察到的行爲差異?

+3

如果'cases'實際上是一個'set',第二個片段不起作用。它碰巧是一個「列表」? – delnan 2013-05-05 18:10:13

+0

兩條評論: (1)你是什麼意思的多線程環境。你在你的Python代碼中創建了多個線程嗎?如果這是代碼,請分享相同的代碼。 (2)您可以將打印件放入您的for循環並嘗試調試。您需要提供更多信息,說明您在每次迭代中如何打印案例的價值。 – vishal 2013-05-05 18:10:47

+0

@delnan對不起,我的意思是列表,沒有設置 – Penguinator 2013-05-05 18:41:17

回答

7

不,第二種格式完全不同。

for循環在循環結束序列上調用iter(),並對結果使用next()調用。考慮它相當於:

iterable = iter(cases): 
while True: 
    try: 
     case = next(iterable) 
    except StopIteration: 
     break 

    # blah 

名單上調用iter()的結果是一個列表迭代器對象:

>>> iter([]) 
<list_iterator object at 0x10fcc6a90> 

此對象保持原來的列表的引用並跟蹤該指數它的在。該索引從0開始並遞增,直到列表完全迭代爲止。

不同的對象可以返回具有不同行爲的不同迭代器。在線程混入的情況下,您最終可能會用其他東西替換cases,但迭代器仍會引用舊序列。

+0

有一個奇怪的例外:一個'__getitem__'接受'range(0,n)'中的整數並引發參數n的'IndexError'的對象可以迭代,而不用'__iter__'方法。我不認爲任何內建類型實際上會這樣做。 – delnan 2013-05-05 18:18:35

+1

你能否澄清這將如何導致他獲得不同的產出? – 2013-05-05 18:18:48

+0

另外,第二個強制python生成一個大列表。 – James 2013-05-05 18:41:01

-1

我沒有得到任何差異,檢查這下面,是什麼ü究竟想..

>>> cases = [1,2,3] 
>>> for case in cases: 
...  print case 
... 
1 
2 
3 
>>> i=0 
>>> for i in range(len(cases)): 
...  print cases[i] 
... 
1 
2 
3 
>>>