2013-05-05 70 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 
>>>