Что localals () ['_ [1]'] означает в Python? - PullRequest
11 голосов
/ 09 марта 2012

Я видел код с одной строкой, который, как утверждается, удаляет дубликаты из последовательности :

u = [x for x in seq if x not in locals()['_[1]']]

Я пробовал этот код в ipython (с Python 2.7), он дал KeyError: '_[1]'

Значит ли ['_[1]'] что-то особенное в Python?

Ответы [ 4 ]

9 голосов
/ 09 марта 2012

locals()['_[1]'] - это способ доступа к ссылке на текущий результат понимания списка (или генератора) внутри этого понимания списка.

Это довольно зло, но может привести к забавным результатам:

>> [list(locals()['_[1]']) for x in range(3)]
[[], [[]], [[], [[]]]]

Подробнее см. Здесь: the-secret-name-of-list-compreations .

7 голосов
/ 09 марта 2012

Это временное имя, используемое для понимания списка в Python 2.6 и более ранних версиях. Python 2.7 и Python 3.x исправили эту бородавку: созданный список больше не доступен, пока создание не завершено.

Или, короче говоря, это была деталь реализации, на которую никто никогда не должен был полагаться.

Здесь вы можете видеть, что Python 2.7 оставляет locals() без изменений, в то время как Python 2.6 создает короткий временный временный:

Python 2.7.2 (default, Jan  5 2012, 16:24:09)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-51)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> def foo():
        t = [list(locals().keys()) for x in range(1) ]
        print(locals())
        print(t[0])

>>> foo()
{'x': 0, 't': [['x']]}
['x']
>>>

Python 2.6.7 (r267:88850, Jan  5 2012, 16:18:48)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-51)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> def foo():
        t = [list(locals().keys()) for x in range(1) ]
        print(locals())
        print(t[0])

>>> foo()
{'x': 0, 't': [['_[1]', 'x']]}
['_[1]', 'x']
>>>

В Python 3.x введен новый кратковременный временный механизм для обработки списка, называемый .0. Не поддавайтесь соблазну использовать это ни для чего. Также понимание всего списка выполняется в отдельном пространстве имен, поэтому переменные цикла также не доступны вне цикла:

Python 3.2 (r32:88445, Jan  5 2012, 16:29:57)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-51)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> def foo():
        t = [list(locals().keys()) for x in range(1) ]
        print(locals())
        print(t[0])

>>> foo()
{'t': [['.0', 'x']]}
['.0', 'x']
3 голосов
/ 09 марта 2012

Вау! Это гадкий загадочный код. Потребовалось немного исследований, чтобы найти ответ.

По сути, понимание списка строит новый список. Он называет этот временный список _[1]. Часть locals() просто использует словарь locals() для поиска этого имени, так как иначе оно недоступно. Так что эта строка говорит ...

[x for x in seq if x not in this_list]

Cryptic.

Найденная информация по этому здесь

1 голос
/ 09 марта 2012

locals() из документов Python:

Обновление и возврат словаря, представляющего текущую локальную таблицу символов.Свободные переменные возвращаются функцией locals (), когда она вызывается в функциональных блоках, но не в блоках классов.

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

Если вы пытаетесь удалить дубликаты из списка, я думаю, что лучший выбор - преобразовать его в set:

In [2]: l = [1,1,3,4,2,4,6]
In [4]: set(l)
Out[4]: set([1, 2, 3, 4, 6])

Если вы хотитесписок снова:

In [5]: list(set(l))
Out[5]: [1, 2, 3, 4, 6]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...