用Python创建一个列表的字典

246

我想创建一个值为列表的字典。例如:

{
  1: ['1'],
  2: ['1','2'],
  3: ['2']
}

如果我执行以下代码:

d = dict()
a = ['1', '2']
for i in a:
    for j in range(int(i), int(i) + 2): 
        d[j].append(i)

我收到一个KeyError错误,因为d[...]不是一个列表。 在这种情况下,在将a赋值后,我可以添加以下代码来初始化字典。

for x in range(1, 4):
    d[x] = list()

有没有更好的方法做到这一点?比方说,在第二个for循环中,我不知道我需要哪些键。例如:

class relation:
    scope_list = list()
...
d = dict()
for relation in relation_list:
    for scope_item in relation.scope_list:
        d[scope_item].append(relation)

替换成其他内容也是一种选择。
d[scope_item].append(relation)
与之配合
if d.has_key(scope_item):
    d[scope_item].append(relation)
else:
    d[scope_item] = [relation,]

最好的处理方式是什么?理想情况下,添加应该“只是工作”。是否有一种表达方式,可以让我在第一次创建列表时就获取到一个空列表字典,即使我不知道每个键名?

7个回答

315
你可以使用 defaultdict
>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> a = ['1', '2']
>>> for i in a:
...   for j in range(int(i), int(i) + 2):
...     d[j].append(i)
...
>>> d
defaultdict(<type 'list'>, {1: ['1'], 2: ['1', '2'], 3: ['2']})
>>> d.items()
[(1, ['1']), (2, ['1', '2']), (3, ['2'])]

1
collections 模块下的其他字典也是这样工作的,例如 collections.OrderedDict - txsaw1
4
哦,太棒了。而且你不必初始化为“=[]”。非常好! - Wilmer E. Henao
1
NameError: name 'a' is not defined - S Andrew

60

你可以使用列表推导式来构建它,就像这样:

>>> dict((i, range(int(i), int(i) + 2)) for i in ['1', '2'])
{'1': [1, 2], '2': [2, 3]}

对于你问题的第二个部分,使用defaultdict

>>> from collections import defaultdict
>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
>>> d = defaultdict(list)
>>> for k, v in s:
        d[k].append(v)

>>> d.items()
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]

41
你可以使用`setdefault`方法:setdefault
d = dict()
a = ['1', '2']
for i in a:
    for j in range(int(i), int(i) + 2): 
        d.setdefault(j, []).append(i)

print d  # prints {1: ['1'], 2: ['1', '2'], 3: ['2']}

名字相当奇怪的setdefault函数的作用是:“获取该键的值,如果该键不存在,则添加该值并返回它。”

正如其他人所指出的那样,defaultdict是更好和更现代的选择。在旧版本的Python(2.5之前)中,setdefault仍然很有用。


2
这个可以工作,但通常最好在可用时使用defaultdict。 - David Z
@David,是的,setdefault 不是最出色的设计,抱歉——它几乎从来不是最佳选择。不过我认为我们(Python 的贡献者)通过 collections.defaultdict 恢复了我们的声誉;-)。 - Alex Martelli
@DavidZ,setdefault与defaultdict不同,因为它更加灵活:否则,你如何为不同的字典键指定不同的默认值呢? - Alex Gidan
@AlexGidan 这是真的,但与这个问题不太相关。 - David Z
当您需要一个有序字典和默认值时,此答案也非常有用。 - nimcap

3

就我个人而言,我只使用JSON将事物转换为字符串以及反向操作。字符串我能理解。

import json
s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
mydict = {}
hash = json.dumps(s)
mydict[hash] = "whatever"
print mydict
#{'[["yellow", 1], ["blue", 2], ["yellow", 3], ["blue", 4], ["red", 1]]': 'whatever'}

2

您的问题已经得到了解答,但是如果我没记错的话,您可以替换以下这些行:

if d.has_key(scope_item):

使用:

if scope_item in d:

那就是说,在这个构造中,d 引用了 d.keys()。有时候 defaultdict 不是最佳选项(例如,如果你想在上述 ifelse 之后执行多行代码),而我发现使用 in 语法更容易阅读。

2

简单的方法是:

a = [1,2]
d = {}
for i in a:
  d[i]=[i, ]

print(d)
{'1': [1, ], '2':[2, ]}

0
如果您是从列表中创建它,那么您也可以在其中使用列表推导式的字典推导式。
dict_of_list_values = {len(k): [name for name in names if len(name) == len(k)] for k in names}

(我在这个例子中使用了一个名称列表)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接