有没有更好的方法在Python中将列表转换为只带键而不带值的字典?
我原以为可以用一行代码把一个列表转换成字典,列表里的每个项目都作为字典的键,而字典则没有值。
我找到的唯一方法却被人反对。
有人说:“用列表推导式但结果又不使用,这样做会让人误解而且效率低。用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 个回答
为了回应最初提问者对性能的担忧(关于在 dict
和 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
模块就在标准库中,可以轻松地进行这些大多数情况下毫无意义的微基准测试!-)
你可以用一个 集合(set) 来代替字典(dict):
>>> myList=['a','b','c','d']
>>> set(myList)
set(['a', 'c', 'b', 'd'])
如果你只需要存放一些不重复的东西,而不需要存储对应的值,这样做会更好。
使用 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 是一个类方法,它会返回一个新的字典。值默认是 None。这个功能在 2.3 版本中新增。