我正在浏览一大堆具有多对多关系的元组,我想制作一个字典,其中(a,b)的每个b都有一个对应于b的所有a的列表。在字典中的键b处测试列表似乎很尴尬,然后查找a,然后在每次通过元组摘要循环时追加a(如果它不存在);但我还没有找到更好的方法。有人存在吗?有没有其他方法可以做到这一点更漂亮?
答案 0 :(得分:55)
setdefault()
方法见the docs:
setdefault(key [,default])
如果关键是 在字典中,返回其值。 如果没有,请插入值为的键 默认和返回默认值。默认 默认为无。
你可以将它作为单个调用使用,如果它存在则会得到b,或者如果它不存在则将b设置为空列表 - 无论哪种方式,返回b:
>>> key = 'b'
>>> val = 'a'
>>> print d
{}
>>> d.setdefault(key, []).append(val)
>>> print d
{'b': ['a']}
>>> d.setdefault(key, []).append('zee')
>>> print d
{'b': ['a', 'zee']}
将此与简单的“不在”检查相结合,您已经完成了三行中的所有操作:
>>> b = d.setdefault('b', [])
>>> if val not in b:
... b.append(val)
...
>>> print d
{'b': ['a', 'zee', 'c']}
答案 1 :(得分:17)
假设您没有真正与列表绑定,defaultdict和set非常方便。
import collections
d = collections.defaultdict(set)
for a, b in mappings:
d[b].add(a)
如果确实想要列表而不是集合,则可以使用
进行操作for k, v in d.iteritems():
d[k] = list(v)
如果你真的想要一个dict而不是一个defaultdict,你可以说
d = dict(d)
但我真的没有看到你想要的任何理由。
答案 2 :(得分:4)
使用collections.defaultdict
your_dict = defaultdict(list)
for (a,b) in your_list:
your_dict[b].append(a)
答案 3 :(得分:3)
而不是使用if
,AFAIK更多 pythonic 来代替使用try
块。
your_list=[('a',1),('a',3),('b',1),('f',1),('a',2),('z',1)]
your_dict={}
for (a,b) in your_list:
try:
your_dict[b].append(a)
except KeyError:
your_dict[b]=[a]
print your_dict
答案 4 :(得分:2)
你可以对你的元组O(n log n)进行排序,然后创建你的字典O(n)
或更简单的O(n),但在许多元组的情况下可能会对内存造成沉重的负担:
your_dict = {}
for (a,b) in your_list:
if b in your_dict:
your_dict[b].append(a)
else:
your_dict[b]=[a]
嗯,它和你描述的几乎一样。这有什么尴尬的?
您还可以考虑使用sql数据库来执行脏工作。
答案 5 :(得分:0)
我不确定你将如何退出关键测试,但是一旦他们的键/值对被初始化就很容易了:)
d = {}
if 'b' not in d:
d['b'] = set()
d['b'].add('a')
该集合将确保集合中只有1个'a'。您需要进行初始'b'检查,以确保键/值存在。
答案 6 :(得分:0)
Dict get
方法?
如果my_dict[some_key]
在字典中,则返回some_key
的值,如果不是,则返回一些默认值(在下面的示例中为[]
):
my_dict[some_key] = my_dict.get(some_key, []).append(something_else)
答案 7 :(得分:0)
另一种方式相当有效(尽管可能不如套装效率高)且简单。它在实践中与defaultdict
类似,但不需要额外导入。
假设您有一个带有空(无)键的字典,这意味着您还可以在某处创建字典键。您可以使用dict.fromkeys
方法执行此操作,此方法还允许为所有键设置默认值。
keylist = ['key1', 'key2']
result = dict.fromkeys(keylist, [])
result
将在哪里:
{'key1':[],'key2':[]}
然后你可以进行循环并直接使用result['key1'].append(..)