Исходное значение списка Python

17

рассмотрим следующий фрагмент кода, который показывает понимание списка.

>>> i = 6
>>> s = [i * i for i in range(100)]
>>> print(i)

Когда вы выполняете пример кода в Python 2.6 , он печатает 99 , но когда вы его выполняете в Python 3.x , он печатает < strong> 6 .

В чем причина изменения поведения и почему вывод 6 в Python 3.x ?

Заранее благодарю вас!

    
задан Joschua 01.01.2011 в 21:45
источник
  • Ничего себе. Мне повезло, что я нашел его здесь, я искал ошибку в течение нескольких недель, если бы наткнулся на это в своем собственном коде. +1 для вопроса, -1 для Python :( –  Kos 01.01.2011 в 21:49
  • Аналогичный вопрос здесь: stackoverflow.com/questions/4198906/... –  Török Gábor 04.05.2011 в 13:27

4 ответа

31

Старое поведение было ошибкой, но не могло быть легко исправлено, поскольку на него ссылался какой-то код.

Переменная i внутри понимания списка должна быть другой i от той, что находится на верхнем уровне. Логически он должен иметь свою собственную область действия, которая не распространяется за пределы понимания, поскольку ее значение имеет смысл только в понимании. Но в Python 2.x из-за детализации реализации область была больше, чем необходимо, заставляя переменную «просачиваться» во внешнюю область видимости, вызывая замешательные результаты.

Python 3.0 был намеренно не предназначен для обратной совместимости с предыдущими версиями, поэтому они использовали возможность исправить это нежелательное поведение.

  

В версиях Python 2.3 и более поздних версиях понимание списка «утечки» управляющих переменных каждого из них содержит в области содержимого. Однако это поведение устарело, и полагаться на него не будет работать в Python 3.0

Источник

    
ответ дан Mark Byers 01.01.2011 в 21:48
источник
7

Да, есть причина, и причина в том, что они не хотели, чтобы временная переменная в понимании списка протекала во внешнее пространство имен. Таким образом, это намеренное изменение, которое является результатом понимания списков, которые теперь являются синтаксическим сахаром для передачи выражения генератора в список ().

Ссылка: PEP3100 .

    
ответ дан Lennart Regebro 01.01.2011 в 21:48
источник
4
Марк Байерс прекрасно ответил на это.

как примечание стороны.
в Python 2.x, если вы измените свои скобки на parens (создавая выражение генератора вместо понимания списка), вы заметите, что управляющая переменная not утечка.

>>> i = 6
>>> s = (i for i in range(100))
>>> print i
6

против.

>>> i = 6
>>> s = [i for i in range(100)]
>>> print i
99

(конечно же, в Python 3 это фиксировано, а в списках отсутствуют больше контрольных переменных)

    
ответ дан Corey Goldberg 01.01.2011 в 22:29
источник
  • Это хороший момент. Но также следует отметить, что s также теперь не содержит список, поэтому, чтобы получить желаемый конечный результат, вы должны сделать список (ы). –  Keith 02.01.2011 в 00:59
0

Похоже на изменение взгляда на меня.

Я подтвердил ваш результат в Python 2.6; он действительно печатает 99, что является последним значением, присвоенным i в понимании списка.

    
ответ дан duffymo 01.01.2011 в 21:50
источник