有没有更好的方法使用键但没有值将列表转换为Python中的字典?

时间:2009-06-20 01:43:49

标签: python list dictionary list-comprehension

我确信会有一个单行将列表转换为字典,其中列表中的项目是键,字典没有值。

我能找到的唯一方法是反对。

“忽略结果时使用列表推导会产生误导和低效。for循环更好”

myList = ['a','b','c','d']
myDict = {}
x=[myDict.update({item:None}) for item in myList]

>>> myDict
{'a': None, 'c': None, 'b': None, 'd': None}

它有效,但还有更好的方法吗?

6 个答案:

答案 0 :(得分:23)

使用dict.fromkeys

>>> my_list = [1, 2, 3]
>>> dict.fromkeys(my_list)
{1: None, 2: None, 3: None}

值默认为None,但您可以将它们指定为可选参数:

>>> my_list = [1, 2, 3]
>>> dict.fromkeys(my_list, 0)
{1: 0, 2: 0, 3: 0}

来自文档:

  

a.fromkeys(seq [,value])创建一个新的   从seq和键的字典   值设置为值。

     

dict.fromkeys是一个类方法   返回一个新词典。值   默认为无。版本2.3中的新功能。

答案 1 :(得分:15)

您可以使用set代替dict:

>>> myList=['a','b','c','d']
>>> set(myList)
set(['a', 'c', 'b', 'd'])

如果您永远不需要存储值,并且只存储无序的唯一项集合,这样会更好。

答案 2 :(得分:5)

要回答原始提问者的性能担忧(对于dict vs set中的查找),有点令人惊讶的是,dict查找可以更快(在Python中) 2.5.1在我相当慢的笔记本电脑上)假设例如一半的查找失败而一半成功。以下是发现的方法:

$ python -mtimeit -s'k=dict.fromkeys(range(99))' '5 in k and 112 in k'
1000000 loops, best of 3: 0.236 usec per loop
$ python -mtimeit -s'k=set(range(99))' '5 in k and 112 in k'
1000000 loops, best of 3: 0.265 usec per loop

多次进行每次检查以验证它们是否可重复。因此,如果慢速笔记本电脑上的30纳秒或更短时间处于绝对关键的瓶颈状态,那么对于模糊的dict.fromkeys解决方案而言,它可能是值得的,而不是简单,明显,可读且清晰正确set (不寻常 - 几乎总是在Python中,简单直接的解决方案也具有性能优势)。

当然,需要检查一个人自己的Python版本,机器,数据以及成功与失败测试的比例,确认非常准确的分析,即削减30纳秒(或其他)这种查找会产生重大影响。

幸运的是,在绝大多数情况下,这将证明是完全没有必要的......但是由于程序员无视微观优化无论如何,无论多少当他们被告知他们的无关紧要时,timeit模块就在标准库中,无论如何都可以轻松地制作那些大多数毫无意义的微基准! - )

答案 3 :(得分:1)

这是使用map执行此操作的一种相当错误且效率低下的方法:

>>> d = dict()
>>> map (lambda x: d.__setitem__(x, None), [1,2,3])
[None, None, None]
>>> d
{1: None, 2: None, 3: None}

答案 4 :(得分:1)

您可以使用列表理解:

my_list = ['a','b','c','d']
my_dict = dict([(ele, None) for ele in my_list])

答案 5 :(得分:1)

也许你可以使用itertools:

>>>import itertools
>>>my_list = ['a','b','c','d']
>>>d = {}
>>>for x in itertools.imap(d.setdefault, my_list): pass
>>>print d
{'a': None, 'c': None, 'b': None, 'd': None}

对于大型列表,也许这非常好:P