dict(list(tuple))vs {list(tuple)}?

时间:2016-05-26 17:20:10

标签: python list dictionary initialization tuples

为什么dict(list(tuple))有效但{list(tuple)}无效 E.g。

>>> dict([('b', 456), ('a', 123)])
{'a': 123, 'b': 456}
>>> {[('b', 456), ('a', 123)]}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

CPython代码的哪一部分允许dict([('b', 456), ('a', 123)])

4 个答案:

答案 0 :(得分:7)

{}可用于集和词典。例如,{8: 2}是字典,但{1, 2, 3, 4}是一个集合。由于您没有给出密钥,因此Python假定您需要一个密钥。一套取决于有可洗物品,所以当你给它一个清单时它就会抱怨。

如果你想使用文字,请尝试理解:

{k: v for k, v in mylist}

答案 1 :(得分:3)

就像["asdf"]list("asdf")str(thing)"thing"一样,在某个东西上调用dict构造函数与使用大括号围绕它完全不同。

当你用大括号构造一个dict时,你应该明确地写出键值对:

{'b': 456, 'a': 123}

当您编写{thing}时,Python会发现您编写了单个项而不是键值对,而是尝试构建包含该thing的单个元素集。这失败了,因为大括号中的东西是一个列表而列表是不可删除的。

使用dict构造函数构造dict时,可以传入用于初始化dict的单个对象。此对象可以是另一个映射,它将被复制到dict中,或者是一系列键值对,表示为元组:

dict([('b', 456), ('a', 123)])

您不能使用冒号表示法:

dict('b': 456, 'a': 123)  # Syntax error

可以使用关键字参数,因为构造函数还允许你提供字符串键作为关键字参数,这是一种括号表示法不支持的语法:

dict(b=456, a=123)  # Works
{b=456, a=123)  # Syntax error

答案 2 :(得分:1)

dict是一个类,当您使用dict(list(tuple))时,它使用构造函数实例化该类。

查看dict的文档:

  

可以通过在大括号中放置逗号分隔的key: value对列表来创建词典,例如:{'jack': 4098, 'sjoerd': 4127}{4098: 'jack', 4127: 'sjoerd'},或者通过dict构造函数。

     

如果没有给出位置参数,则创建一个空字典。如果给出位置参数并且它是映射对象,则创建具有与映射对象相同的key-value对的字典。否则,位置参数必须是iterable对象。 iterable中的每个项目本身必须是iterable,只有两个对象。每个项目的第一个对象成为新词典中的一个键,第二个对象成为相应的值。如果一个键出现多次,该键的最后一个值将成为新词典中的相应值。 / p>

当您使用{list(tuple)}时,它会尝试创建一个set对象。

  

set对象是不同hashable个对象的无序集合。

但是你在这里使用了一个列表元素,它是一个可变容器并且不可导致导致错误:

TypeError: unhashable type: 'list'

Why Lists Can't Be Dictionary Keys?有一个很好的解释,同样的行为也适用于集合成员。

答案 3 :(得分:0)

dict(list(tuple))使用dict()构造函数创建一个新的dict。这就是他的所作所为

def __init__(self, seq=None, **kwargs): # known special case of dict.__init__
        """
        dict() -> new empty dictionary
        dict(mapping) -> new dictionary initialized from a mapping object's
            (key, value) pairs
        dict(iterable) -> new dictionary initialized as if via:
            d = {}
            for k, v in iterable:
                d[k] = v
        dict(**kwargs) -> new dictionary initialized with the name=value pairs
            in the keyword argument list.  For example:  dict(one=1, two=2)
        """

如果您使用{list(tuple)},则使用设置文字。它会创建一个新的set,而不是dict对于 dict文字,您需要至少一对由冒号分隔的两个值。 (不要问我为什么;)。这是Python的定义

要创建setdict,密钥(dict)或值(set)必须是可清除的。定义说:

  

如果对象具有永不更改的哈希值,则该对象是可清除的   在其一生中

list是一个可变序列。所以list是不可取的。这就是你收到错误消息的原因

TypeError: unhashable type: 'list'

如果您想使用dict创建新的list(tuple)使用大括号,则可以使用 dict comprehension 。 (但只支持 Python 3

{a,b for a,b in list(tuple)}

P / S: dict literals dict()

更具性能