Dict / Set解析顺序一致性 [英] Dict/Set Parsing Order Consistency

查看:114
本文介绍了Dict / Set解析顺序一致性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用可散乱对象(例如 dict 键或设置项目的容器)。因此,字典只能具有一个值为 1 1.0 True 等(注意:简化了一些 - 哈希冲突是允许的,但这些值被认为是相等的)

Containers that take hashable objects (such as dict keys or set items). As such, a dictionary can only have one key with the value 1, 1.0 or True etc. (note: simplified somewhat - hash collisions are permitted, but these values are considered equal)

我的问题是:解析顺序明确的定义是可以实现的结果对象吗?例如,OSX Python 2.7.11和3.5.1解释为 dict ,如下所示:

My question is: is the parsing order well-defined and is the resulting object predictable across implementations? For example, OSX Python 2.7.11 and 3.5.1 interprets dict like so:

>>> { True: 'a', 1: 'b', 1.0: 'c', (1+0j): 'd' }
{True: 'd'}

在这种情况下,似乎保留了第一个键和最后一个值。

In this case, it appears that the first key and the last value are preserved.

类似,在设置的情况下:

>>> { True, 1, 1.0, (1+0j) }
set([(1+0j)])

这样看来,最后一个项目被保留。

Here it appears that the last item is preserved.

但是(如评论中所述):

But (as mentioned in comments):

>>> set([True, 1, 1.0])
set([True])

文档注意到项目的顺序(例如在 dict.items )是未定义的,但是我的问题是指构建 dict set

The documentation notes that the order of items (for example in dict.items) is undefined, however my question refers to the result of constructing dict or set objects.

推荐答案

词典显示


如果以逗号分隔的键/基准对序列给出,它们从左到右被评估以定义字典的条目:每个关键对象被用作字典中的键以存储对应的基准。这意味着您可以在键/基准列表中多次指定相同的键,并且该键的最终字典的值将是给定的最后一个。

If a comma-separated sequence of key/datum pairs is given, they are evaluated from left to right to define the entries of the dictionary: each key object is used as a key into the dictionary to store the corresponding datum. This means that you can specify the same key multiple times in the key/datum list, and the final dictionary’s value for that key will be the last one given.

理解与列表和设置理解相反,需要两个用冒号分隔的表达式,后跟通常的for和if子句。当理解运行时,生成的键和值元素按照它们生成的顺序插入到新字典中。

A dict comprehension, in contrast to list and set comprehensions, needs two expressions separated with a colon followed by the usual "for" and "if" clauses. When the comprehension is run, the resulting key and value elements are inserted in the new dictionary in the order they are produced.

设置显示

一个设置的显示产生一个新的可变集集对象,内容由表达式序列或理解指定。当提供逗号分隔的表达式列表时,其元素将从左到右进行评估,并添加到set对象中。当提供理解时,该集合是从理解结果中构建的。

A set display yields a new mutable set object, the contents being specified by either a sequence of expressions or a comprehension. When a comma-separated list of expressions is supplied, its elements are evaluated from left to right and added to the set object. When a comprehension is supplied, the set is constructed from the elements resulting from the comprehension.

调用集合构造函数有所不同或使用理解和平原文字。

There is a difference in calling the set constructor or using a comprehension and the plain literal.

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 字节码当您传递纯文字时,用逗号分隔:

Python only runs the BUILD_SET bytecode when you pass a pure literal separated by commas as per:

当提供逗号分隔的表达式列表时,其元素从左到右进行评估,并添加到设置对象中。

When a comma-separated list of expressions is supplied, its elements are evaluated from left to right and added to the set object.

理解行:

当提供理解时,该集合是从理解结果中构建的。

所以感谢Hamish的备案一个错误报告确实归结为 BUILD_SET 操作码根据Raymond Hettinger在链接中的评论的罪魁祸首是在 Python / ceval.c ,它不必要地向后循环,其实现如下:

So thanks to Hamish filing a bug report it does indeed come down to the BUILD_SET opcode as per Raymond Hettinger's comment in the link The culprit is the BUILD_SET opcode in Python/ceval.c which unnecessarily loops backwards, the implementation of which is below:

 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();
        }

这篇关于Dict / Set解析顺序一致性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆