2015-04-24 3 views
2

я нигде не могу найти, что определяет такое поведение:Переменные, определенные внутри списка, попадают в область охвата?

if [x for x in [0, 1, -1] if x > 0]: 
    val = x 

Насколько безопасен этот код? Будет ли назначаться последнему элементу в списке, если какой-либо элемент в списке больше 0?

+0

Я пробовал это (на python 2.6.6, но я думаю, это не так уж много), и для меня он дал -1 в качестве результата. Я предполагаю, что это связано с тем, как работает понимание списка. Я * думаю *, что сначала значение заменяется, а затем проверяется на предложение if. (Кстати, я немного удивлен тем, что x находится в области вне понимания ...) – Attilio

+0

Спасибо, я сделал опечатку в вопросе, val, похоже, всегда равен -1 в конце цикла. Я предполагаю, что если есть список, возвращаемый, то x всегда останется равным последнему элементу в списке, или, по крайней мере, так оно и есть. Я тоже был удивлен, что x все еще находится в сфере действия. –

+1

@MatthewTodd val, похоже, соответствует последнему элементу в списке, когда я использовал вышеприведенный код и добавил больше элементов в список. На стороне примечание: 'print [x for x в [0, 1, -1], если x> 0]' prints '[1]'. Тем не менее, это не работает в python 3. – Matthew0898

ответ

3

В Python 2.x, переменные, определенные внутри списковых просочиться в их область видимости, так что да, val всегда будут связаны с последним значением, связанным с x в течение списка понимания (до тех пор, как результат понимание является непустым и, следовательно, «правдивым», списком). не

Однако в Python 3.x, это уже не так:

>>> x = 'foo' 
>>> if [x for x in [0, 1, -1] if x > 0]: 
...  val = x 
... 
>>> val 
'foo' 

Поведение (чуть-чуть) документально here:

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

... с изменением Python 3.x документированной here:

[...] Обратите внимание, что в представлениях списков есть различная семантика: они ближе к синтаксическому сахару для выражения генератора внутри конструктора list(), и, в частности, переменные управления циклом больше не просачиваются в окружающую область.

Казалось бы, что поведение 2.x не было что-то кто-то особенно гордился, а на самом деле Гвидо ван Россум относится к нему как «один из„маленьких грязных секретов“Питона» в blog post.

-3

Не так ли проще?

for x in [0, 1, -1]: 
    if x > 0: 
     val = x 
+0

Можете ли вы это объяснить? –

+0

Это не дает того же результата. Код в моем вопросе будет присваивать var последнему элементу в списке, если какой-либо элемент списка больше 0, когда ваш будет возвращать последний элемент в списке, который больше 0. –

Смежные вопросы