Ответ 1
- Теперь исправлена ошибка в последних версиях python, как описано в @jsf answer
Если задана разделенная запятыми последовательность пар ключ /datum, они вычисляются слева направо для определения записей словаря: каждый ключевой объект используется в качестве ключа в словаре для хранения соответствующей базы данных. Это означает, что вы можете указать один и тот же ключ несколько раз в списке key/datum, и последнее значение словаря для этого ключа будет последним.
В понимании dict, в отличие от списка и набора понятий, нужны два выражения, разделенные двоеточием, за которыми следуют обычные предложения "для" и "если". Когда понимание выполняется, результирующие элементы ключа и значения вставляются в новый словарь в том порядке, в котором они создаются.
Отображение набора дает новый изменяемый заданный объект, содержимое которого задается либо последовательностью выражений, либо пониманием. Когда предоставляется список выражений, разделенных запятыми, его элементы оцениваются слева направо и добавляются к заданному объекту. Когда предоставляется понимание, набор создается из элементов, полученных в результате понимания.
Существует разница в вызове конструктора set или использовании понимания и простого литерала.
def f1():
return {x for x in [True, 1]}
def f2():
return set([True, 1])
def f3():
return {True, 1}
print(f1())
print(f2())
print(f3())
import dis
print("f1")
dis.dis(f1)
print("f2")
dis.dis(f2)
print("f3")
dis.dis(f3)
Вывод:
{True}
{True}
{1}
Как они созданы, влияет на результат:
605 0 LOAD_CONST 1 (<code object <setcomp> at 0x7fd17dc9a270, file "/home/padraic/Dropbox/python/test.py", line 605>)
3 LOAD_CONST 2 ('f1.<locals>.<setcomp>')
6 MAKE_FUNCTION 0
9 LOAD_CONST 3 (True)
12 LOAD_CONST 4 (1)
15 BUILD_LIST 2
18 GET_ITER
19 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
22 RETURN_VALUE
f2
608 0 LOAD_GLOBAL 0 (set)
3 LOAD_CONST 1 (True)
6 LOAD_CONST 2 (1)
9 BUILD_LIST 2
12 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
15 RETURN_VALUE
f3
611 0 LOAD_CONST 1 (True)
3 LOAD_CONST 2 (1)
6 BUILD_SET 2
9 RETURN_VALUE
Python запускает только байт-код BUILD_SET
, когда вы передаете чистый литерал, разделенный запятыми, следующим образом:
Когда предоставляется список выражений, разделенных запятыми, его элементы оцениваются слева направо и добавляются к заданному объекту.
Линия для понимания:
Когда предоставляется понимание, набор создается из элементов, полученных в результате понимания.
Итак, благодаря тому, что Хэмиш подал отчет об ошибке , он действительно подходит к коду BUILD_SET
в соответствии с комментарием Раймонда Хеттингера в ссылке Претендентом является код операции BUILD_SET в Python/ceval.c, который излишне петли назад, реализация которого ниже:
TARGET(BUILD_SET) {
PyObject *set = PySet_New(NULL);
int err = 0;
if (set == NULL)
goto error;
while (--oparg >= 0) {
PyObject *item = POP();
if (err == 0)
err = PySet_Add(set, item);
Py_DECREF(item);
}
if (err != 0) {
Py_DECREF(set);
goto error;
}
PUSH(set);
DISPATCH();
}