Найти - Пользователи
Полная версия: Генератор списка (list comprehensions). Оператор присваивания.
Начало » Python для новичков » Генератор списка (list comprehensions). Оператор присваивания.
1 2
soln
Приветствую.

Не подскажите (или дайте сылку) почему в list comprehensions не льзя использовать оператор присваивания?

In [1]: li = [1,'sd', [], {}]
In [2]: [ type(x) for x in li]
Out[2]: [int, str, list, dict]
In [3]: [x.append('3') for x in li if isinstance(x, list) ]
Out[3]: [None]
In [4]: li
Out[4]: [1, 'sd', ['3'], {}]
In [5]: x
Out[5]: {}

То есть из писка видно li, и более того из области видимости где был объявлен генератор списка в доступна имя x присвоенное for.

In [6]: x = 89
In [7]: [x.append('3') for x in li if isinstance(x, list) ]
Out[7]: [None]
In [8]: x
Out[8]: {}
Об этом в прочем написано у бизли.
Глава 6. Функции и функциональное программирование
"Наконец, важно отметить, что в Python 2 переменные циклов, определяе-
мые внутри генератора списков, размещаются в текущей области видимо-
сти и остаются доступными по завершении работы генератора списка. На-
пример, переменная цикла x, используемая в генераторе списков [x for x in
a], получит значение, которое затрет значение, хранившееся в ней ранее,
и по завершении работы генератора оно будет равно значению последнего
элемента полученного списка. К счастью, эта проблема была решена в Py-
thon 3, где переменная цикла остается частной.

Однако.
In [9]: a = 0
In [10]: [a += 1 for x in li if isinstance(x, list) ]
  File "<ipython-input-10-0e620fdd4eff>", line 1
    [a += 1 for x in li if isinstance(x, list) ]
        ^
SyntaxError: invalid syntax
In [11]: [a = 1 for x in li if isinstance(x, list) ]
  File "<ipython-input-11-83001fa94297>", line 1
    [a = 1 for x in li if isinstance(x, list) ]
       ^
SyntaxError: invalid syntax

Почему нельзя использовать ‘=’
dimy44
ну, допустим гипотетически, что
[a = 1 for x in li if isinstance (x, list)]
корректная запись. Каков, по-вашему, должен быть список по завершению цикла? Инструкция а = 1 присваивает переменной а значение, но это же не функция, которая что-то возвратит.
JOHN_16
soln
нельзя потому что это лишено смысла. Предположим что происходит N итераций, тогда , согласно вашей идее, N раз будет вызван код a = 1. Ну и какой в этом смысл? Интерпретатор не быдло, он с первого раза поймет что a=1, не нужно это ему вдалбливать что бы до него дошло.

Ну и вообще то это ошибка синтаксиса - тут не о чем больше говорить.

я перечитал еще раз ваш пост, какая то каша получается. Где вы тут нашли противоречия?
soln
dimy44
Каков, по-вашему, должен быть список по завершению цикла? Инструкция а = 1 присваивает переменной а значение, но это же не функция, которая что-то возвратит.

Это пожауй хороший вопрос. Спасибо.
На сколько я знаю, операция присваивания ничего не вернет.
То есть в конце я ожидал бы увидить пустой список

а что вернется в список если ‘x’ не поподет под условия?
In [1]: li = [1,'sd', {}]
In [2]: [x.append('3') for x in li if isinstance(x, list) ]
Out[2]: []

Я понимаю что подобные операции не явны, а это противоречет идеологии.
Однако меня скорей интересует почему нельзя ‘=’ а ‘if’ можно


soln
JOHN_16
solnнельзя потому что это лишено смысла. Предположим что происходит N итераций, тогда , согласно вашей идее, N раз будет вызван код a = 1. Ну и какой в этом смысл? Интерпретатор не быдло, он с первого раза поймет что a=1, не нужно это ему вдалбливать что бы до него дошло.
ммм. Ну не знаю. Я возможно не прав, но ведь при такой логике можно получить исключеине
ЗадачаБессмысленна: Ошибок в коде нет, но задача не имеет смысла.
Ну если серьезно то следить за смыслов пока всеже дело человека .

JOHN_16
Где вы тут нашли противоречия?
Я не понимаю почему если генератор списка с вложенным условием не попадает не разу под условие то возвращает пустой список, а если внутри генератора использывать оператор присваивания возвращается исключение.

За кашу извините.
JOHN_16
soln
Я не понимаю почему если генератор списка с вложенным условием не попадает не разу под условие то возвращает пустой список
потому что это генератор списка и на выходе он должен вернуть список. Каков именно механизм я вам не скажу. Даже пофантазировав можно прийти к выводу что он сперва создает пустой список потом его наполняет и возвращает, а то что по условиям список ничем не наполнился его не волнует - он сделал все четко по своим алгоритмам.
soln
если внутри генератора использывать оператор присваивания возвращается исключение
вам же явно указано что это ошибка синтаксиса - не заложено в синтаксисе языка программирования такая запись. Если вы и на этот ответ хотите задать вопрос почему - то обращайтесь к создателям языка.
bismigalis
определение list comprehension:

A list comprehension consists of brackets containing an expression(выражение) followed by a for clause, then zero or more for or if clauses.

= это оператор присваивания

в python2
>>> [print 1 for x in xrange(1)]
  File "<stdin>", line 1
    [print 1 for x in xrange(1)]
         ^
SyntaxError: invalid syntax

в python3
>>> [print(1) for x in range(1)]
1
[None]
dimy44
>> На сколько я знаю, операция
присваивания ничего не вернет.
Не так. Тут просто даже нет такого понятия, это абсурдно. Как, скажем, list.append(a=1) или print a=1. Да и list comprehensions имхо не для такого использования предназначен, для этого есть цикл for в явном виде, где можно отделить мух от котлет: где надо - выполнять присваивание, где надо- добавлять элементы в список …, а юзать list comprehensions ради побочного эффекта и получать на выходе список с кучей None (например) неразумно.
FishHook
В list comprehensions оно конечно не нужно, но в лямбдах ИМХО было бы не лишним.
dimy44
ну в лямбдах setattr можно. Для неглобальных…
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB