语言规范似乎无法保证集合文字中元素的插入顺序。但是,Python 3.6 已更改,因此它具有预期的从左到右的计算顺序。有关此更改的完整详细信息,请参阅以下issue,还有commit这引入了插入顺序的变化。
为了更详细地描述变化,构建集合文字{True, 1}
触发BUILD_SET
第一次将指针推入后的操作码(oparg 等于 2)True
and 1
到虚拟机的内部堆栈。
在Python 3.4中,BUILD_SET使用以下循环将元素插入集合中(请注意,在我们的示例中 oparg 为 2):
while (--oparg >= 0) {
PyObject *item = POP();
if (err == 0)
err = PySet_Add(set, item);
Py_DECREF(item);
Since 1
最后添加到堆栈中,它首先被弹出,并且是第一个插入到集合中的对象。
在较新版本的 Python(例如 3.6)中,BUILD_SET操作码使用PEEK
代替POP
:
for (i = oparg; i > 0; i--) {
PyObject *item = PEEK(i);
if (err == 0)
err = PySet_Add(set, item);
Py_DECREF(item);
PEEK(i) fetches the ith item down the stack, so for {True, 1}
, the object True
is added to the set first.