有没有更好的方法在Python中将列表转换为只带键而不带值的字典?

6 投票
6 回答
1344 浏览
提问于 2025-04-15 12:23

我原以为可以用一行代码把一个列表转换成字典,列表里的每个项目都作为字典的键,而字典则没有值。

我找到的唯一方法却被人反对。

有人说:“用列表推导式但结果又不使用,这样做会让人误解而且效率低。用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 个回答

5

为了回应最初提问者对性能的担忧(关于在 dictset 中查找的速度),有点出乎意料的是,在某些情况下,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 模块就在标准库中,可以轻松地进行这些大多数情况下毫无意义的微基准测试!-)

15

你可以用一个 集合(set) 来代替字典(dict):

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

如果你只需要存放一些不重复的东西,而不需要存储对应的值,这样做会更好。

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 是一个类方法,它会返回一个新的字典。值默认是 None。这个功能在 2.3 版本中新增。

撰写回答