2014-02-21 3 views
4

У меня есть словарь списков, и я хочу объединить их в один список namedtuples. Я хочу, чтобы первый элемент всех списков в первом кортеже, второй во втором и т. Д.«Zip» словарь списков в Python

Пример:

{'key1': [1, 2, 3], 'key2': [4, 5, 6], 'key3': [7, 8, 9]} 

И я хочу полученный список, чтобы быть похожим на это:

[('key1': 1, 'key2': 4, 'key3': 7), 
('key1': 2, 'key2': 5, 'key3': 8), 
('key1': 3, 'key2': 6, 'key3': 9)] 

Я предполагаю, что есть элегантный способ сделать это?

Edit:

я сравнил работы времена namedtuple ответа @Steve Джессоп к словарной версии по @Ashwini Чаудхари и бывший несколько быстрее:

d = {key: numpy.random.random_integers(0, 10000, 100000) 
     for key in ['key1', 'key2', 'key3']} 

Avg. 100 трасс:

namedtuple and map: 0.093583753109 
namedtuple and zip: 0.119455988407 
dictionary and zip: 0.159063346386 
+1

Словари - не отсортированные структуры данных. Вы что-то пробовали? – msvalkon

+0

Обновлен вопрос, а точнее. На самом деле я еще ничего не пробовал ... – rongved

ответ

5

Сначала получите ключи. Вы можете сортировать их или что угодно, на этом этапе. Возможно, вы знаете, какие ключи использовать в каком порядке, поэтому вам не нужно проверять данные.

keys = list(d.keys()) 

Определить именованный кортеж:

Record = collections.namedtuple('Record', keys) 

итерацию все списки параллельно:

[Record(*t) for t in zip(*(d[k] for k in keys))] 

list(map(Record, *(d[k] for k in keys))) или если вы хотите map.

Обратите внимание, что если keys просто list(d.keys()), то вы можете использовать d.values() вместо (d[k] for k in keys), потому что даже если порядок ключей в словаре произвольности гарантированно будет таким же, как и порядок значений. Так что, если вы не заботитесь о порядке полей в namedtuple то упрощается:

Record = collections.namedtuple('Record', d.keys()) 
[Record(*t) for t in zip(*(d.values()))] 

или list(map(Record, *d.values())), если Вам нравится map.

+0

+1 thx для гарантии;) – zhangxaochen

5
>>> d = {'key1': [1, 2, 3], 'key2': [4, 5, 6], 'key3': [7, 8, 9]} 
>>> keys = d.keys() 
>>> [dict(zip(keys, vals)) for vals in zip(*(d[k] for k in keys))] 
[{'key3': 7, 'key2': 4, 'key1': 1}, 
{'key3': 8, 'key2': 5, 'key1': 2}, 
{'key3': 9, 'key2': 6, 'key1': 3}] 
Смежные вопросы