Python创建列表字典

问题:Python创建列表字典

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

{
  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,]

处理此问题的最佳方法是什么?理想情况下,追加将“有效”。有什么方法可以表达我想要空列表的字典,即使我第一次创建列表时也不知道每个键?

I want to create a dictionary whose values are lists. For example:

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

If I do:

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

I get a KeyError, because d[…] isn’t a list. In this case, I can add the following code after the assignment of a to initialize the dictionary.

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

Is there a better way to do this? Lets say I don’t know the keys I am going to need until I am in the second for loop. For example:

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

An alternative would then be replacing

d[scope_item].append(relation)

with

if d.has_key(scope_item):
    d[scope_item].append(relation)
else:
    d[scope_item] = [relation,]

What is the best way to handle this? Ideally, appending would “just work”. Is there some way to express that I want a dictionary of empty lists, even if I don’t know every key when I first create the list?


回答 0

您可以使用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'])]

You can use 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

您可以使用列表理解来构建它,如下所示:

>>> 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])]

You can build it with list comprehension like this:

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

And for the second part of your question use 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])]

回答 2

您可以使用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是一个更好,更现代的选择。 setdefault在旧版本的Python(2.5之前的版本)中仍然有用。

You can use 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']}

The rather oddly-named setdefault function says “Get the value with this key, or if that key isn’t there, add this value and then return it.”

As others have rightly pointed out, defaultdict is a better and more modern choice. setdefault is still useful in older versions of Python (prior to 2.5).


回答 3

您的问题已得到解答,但是IIRC您可以替换以下行:

if d.has_key(scope_item):

与:

if scope_item in d:

也就是说,该构造中的d参考d.keys()。有时defaultdict并不是最好的选择(例如,如果您想在else与上面的内容关联后执行多行代码if),并且我发现in语法更易于阅读。

Your question has already been answered, but IIRC you can replace lines like:

if d.has_key(scope_item):

with:

if scope_item in d:

That is, d references d.keys() in that construction. Sometimes defaultdict isn’t the best option (for example, if you want to execute multiple lines of code after the else associated with the above if), and I find the in syntax easier to read.


回答 4

就个人而言,我只是使用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'}

Personally, I just use JSON to convert things to strings and back. Strings I understand.

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'}

回答 5

简单的方法是:

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

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

easy way is:

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

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