6

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

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

“在忽略结果时使用列表推导会产生误导且效率低下。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}

它有效,但有没有更好的方法来做到这一点?

4

6 回答 6

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,值设置为 value。

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

于 2009-06-20T01:48:05.927 回答
15

您可以使用集合而不是字典:

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

如果您从不需要存储值,而只是存储唯一项目的无序集合,这会更好。

于 2009-06-20T01:49:34.363 回答
5

为了回答最初提问者的性能担忧(对于dictvs中的查找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

于 2009-06-20T05:37:39.897 回答
1

这是使用地图的一种相当错误且效率低下的方法:

>>> d = dict()
>>> map (lambda x: d.__setitem__(x, None), [1,2,3])
[None, None, None]
>>> d
{1: None, 2: None, 3: None}
于 2009-06-20T01:54:00.733 回答
1

您可以使用列表推导:

my_list = ['a','b','c','d']
my_dict = dict([(ele, None) for ele in my_list])
于 2009-06-20T07:04:57.713 回答
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

于 2009-06-20T09:33:52.310 回答