2013-05-05 3 views
3

Может ли кто-нибудь сказать мне, как реализованы петли Python? Причина, почему я спрашиваю это потому, что я получаю различное поведение в двух следующих за петлю, когда я ожидаю, что такое же поведение (при условии, cases просто набор элементов):Реализация Python для цикла

Первый цикла:

for case in cases: 
    blah 

Второй цикл:

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

Я бегу мой код в многопоточном среде.

В принципе, мне интересно, является ли цикл Python для цикла по набору (как в первом для цикла) просто быстрым способом второго. Что именно происходит, когда мы используем цикл python for, и есть ли какая-либо основная оптимизация/реализация, которая может вызывать разницу в поведении, которую я наблюдаю?

+3

Если 'cases' фактически' set', второй фрагмент кода не работает. Случается, что это «список»? – delnan

+0

Два комментария: (1) Что вы подразумеваете под многопоточной средой. Вы создали несколько потоков в коде Python? Если это код, пожалуйста, поделитесь этим кодом. (2) Вы можете поместить отпечатки в свои циклы и попытаться отладить. Вам нужно больше информации о том, что именно такое поведение говорит о том, что вы пытаетесь напечатать значение case на каждой итерации. – vishal

+0

@ delnan Извините, что я имел ввиду список, а не – Penguinator

ответ

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) 'и генерирует' IndexError' для параметра n, может быть итерирован без метода '__iter__'. Я не думаю, что любые встроенные типы на самом деле это делают. – delnan

+1

не могли бы вы объяснить, как это может заставить его получить разные результаты? –

+0

Кроме того, второй силовой питон генерирует большой список. – James

-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 
>>> 
Смежные вопросы