在Python词典理解中为单个键添加多个值

时间:2015-10-12 13:03:25

标签: python dictionary

我想学习如何使用字典理解,并决定使用一个用于之前解决的任务。我需要为同一个键分配多个值。我想知道是否有更好的方式来实现我想要做的事情而不是到目前为止我写的代码。

graph = {(x1,y1): [(c,d) for a,b,c,d in data if a == x1 and b == y1] for x1 ,y1, x2, y2 in data}

例如我有这个:

data = {(1,2,1,5),(1,2,7,2),(1,5,4,7),(4,7,7,5)}

前两个值应创建一个键,其余两个值应作为键的值添加。 在给出的示例中,我想返回:

{(1, 2): [(1, 5), (7, 2)], (1, 5): [(4, 7)], (4, 7): [(7, 5)]}

是否有更简单的方法来迭代整个数据只是为了找到匹配的值?

4 个答案:

答案 0 :(得分:2)

实际上,你的词汇理解并不是一种有效的方法。它不包含一个而是两个用于同一数据集的循环,不必要。

在这里使用简单的for循环更加pythonic:

from collections import defaultdict

data = {(1,2,1,5),(1,2,7,2),(1,5,4,7),(4,7,7,5)}
output = defaultdict(list)

for a, b, c, d in data:
    output[a, b].append((c, d))

答案 1 :(得分:1)

您的代码很整洁,但时间复杂度为O(n ^ 2),可以减少为O(n)。

data = {(1,2,1,5),(1,2,7,2),(1,5,4,7),(4,7,7,5)}
result = dict()
for item in data:
    key = (item[0],item[1])
    value = result.setdefault(key,[])
    value.append((item[2],item[3]))
    result[key] = value
print result

在我看来,使用for循环可以使代码更全面

答案 2 :(得分:1)

我不知道这是否是最佳答案,但我会做同样的事情:

m_dict = {}
for val in data:
    key = (val[0],val[1])
    if key in m_dict:
        m_dict[key].append((val[2],val[3]))
    else:
        m_dict[key] = [(val[2],val[3])]

或者更简洁地使用setdefault

m_dict = {}
for val in data:
    key = (val[0],val[1])
    obj = m_dict.setdefault(key,[])
    obj.append((val[2],val[3]))

答案 3 :(得分:0)

在这种情况下,我会使用itertools.groupby。以你的例子:

dict(groupby(data, lambda t: (t[0], t[1])))

这将生成一个密钥等于(1, 2), (1, 5), and (4, 7)的dict,以及由(1, 2, 1, 5), (1, 2, 7, 2)...组成的值,这对于大多数用途来说应该足够了。如果需要,您还可以对分组列表进行后处理。

如下面的评论中所述,groupby需要排序数据。因此,您需要在分组之前进行排序,并且可能希望将迭代器强制转换为列表:

first_two = lambda tup: (tup[0], tup[1])
groups = groupby(sorted(data, key=first_two), first_two)
target = {k: list(g) for k, g in groups}