字典理解与嵌套列表,防止覆盖

时间:2015-06-11 10:48:54

标签: python list dictionary

我正在尝试使用嵌套列表来使用字典理解。只要键是唯一的,一切正常。但是,如果存在多个键,我想将值附加到该键而不是覆盖该值。这可能是理解吗?

seq1 = [[1, [1,2,3,4]], [2, [5,6,7]]]
seq2 = [[1, [1,2,3,4]], [1, [5,6,7]]]

print {key: [val] for key, val in seq1}  # Or dict(seq1)
>>> {1: [[1, 2, 3, 4]], 2: [[5, 6, 7]]}

print {key: [val] for key, val in seq2}
>>> {1: [[5, 6, 7]]}  # First value is overwritten

# Desired output:
def index_reads(reads):
    result = {}
    for i in reads:
        d = dict([i])
        for key, val in d.iteritems():
            if key in result:
                result[key].append(val)
            else:
                result[key] = [val]
    return result

print index_reads(seq1)
>>> {1: [[1, 2, 3, 4]], 2: [[5, 6, 7]]}

print index_reads(seq2)
>>> {1: [[1, 2, 3, 4], [5, 6, 7]]}

抱歉,我找不到重复这个问题。

3 个答案:

答案 0 :(得分:2)

您不需要列表理解。作为一种更加pythonic的方式,您可以使用dict.setdefault()方法:

>>> d={key: [val] for key, val in seq1}
>>> for key, val in seq2:
...   d.setdefault(key,[]).append(val)
... 
>>> d
{1: [[1, 2, 3, 4], [1, 2, 3, 4], [5, 6, 7]], 2: [[5, 6, 7]]}

您也可以使用collections.defaultdict执行此类任务。

如果您在seq2中使用不同的密钥,例如:

,它也会显示其功能
>>> seq2 = [[1, [1,2,3,4]], [5, [5,6,7]]]
>>> d={key: [val] for key, val in seq1}
>>> for key, val in seq2:
...   d.setdefault(key,[]).append(val)
... 
>>> d
{1: [[1, 2, 3, 4], [1, 2, 3, 4]], 2: [[5, 6, 7]], 5: [[5, 6, 7]]}

如果您不想保留重复内容,可以使用defaultdict set作为容器:

>>> from collections import defaultdict
>>> seq1 = [[1, [1,2,3,4]], [2, [5,6,7]]]
>>> seq2 = [[1, [1,2,3,4]], [1, [5,6,7]]]
>>> 
>>> d=defaultdict(set)
>>> for key, val in seq1+seq2:
...   d[key].add(tuple(val))
... 
>>> d
defaultdict(<type 'set'>, {1: set([(5, 6, 7), (1, 2, 3, 4)]), 2: set([(5, 6, 7)])})

答案 1 :(得分:1)

您可以使用groupby中的itertools

import itertools
import operator

seq1 = [[1, [1,2,3,4]], [2, [5,6,7]]]
seq2 = [[1, [1,2,3,4]], [1, [5,6,7]]]

def index_reads(seq):
    return {k: [i[1] for i in g] for k, g in itertools.groupby(seq, operator.itemgetter(0))}

print index_reads(seq1)
print index_reads(seq2)

输出

{1: [[1, 2, 3, 4]], 2: [[5, 6, 7]]}   
{1: [[1, 2, 3, 4], [5, 6, 7]]}

答案 2 :(得分:0)

是的,使用defaultdict也可以:

from collections import defaultdict

seq1 = [[1, [1,2,3,4]], [2, [5,6,7]]]
seq2 = [[1, [1,2,3,4]], [1, [5,6,7]]]

d={key: [val] for key, val in seq1}
d = defaultdict(list)
for key, val in seq2:
    d[key].append(val)

print d

然后:

[(1, [[1, 2, 3, 4], [5, 6, 7]])

或者如果我们删除seq1,

seq2 = [[1, [1,2,3,4]], [1, [5,6,7]]]
d={key: [val] for key, val in seq2}
d = defaultdict(list)
for key, val in seq2:
    d[key].append(val)
print d

你将再次拥有:

defaultdict(<type 'list'>, {1: [[1, 2, 3, 4], [5, 6, 7]]})