2015-06-11 22 views
1

Я пытаюсь использовать понимание словаря с помощью вложенного списка. Пока ключи уникальны, все работает нормально. Однако, если есть кратные ключевые данные, я хотел бы добавить значения к этому ключу, а не переписывать значение. Возможно ли это, используя понимание?Учет словаря с вложенным списком, предотвращение перезаписи

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

Извините, я не мог найти повторение этого вопроса.

ответ

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

Вам не нужен список. В качестве более вещий образом, вы можете использовать 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

или использовать 'defaultdict' –

+0

@KarolyHorvath Да, на самом деле;) – Kasramvd

+0

Спасибо Я буду смотреть, но вывод немного отличается от ожидаемого. Сейчас я отредактирую, извините. – kezzos

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]]}) 
+0

Если seq1 не существует, что мне делать. – kezzos

Смежные вопросы