pythonic (3) способ отобразить 2 дикта списков в 1 список диктов - PullRequest
1 голос
/ 22 сентября 2019

Это что-то вроде:

num_dict  = {'number':[1,2,3]}
lett_dict = {'letter': ['a','b','c']}

, чтобы стать:

[{'number':1,'letter':'a'},{'number':2,'letter':'b'},{'number':3,'letter':'c'}]

РЕДАКТИРОВАТЬ

, говоря иначе:

{'number': [1, 2, 3], 'letter': ['a', 'b', 'c'],'symbol':['$','%','^']}

стать

[{'number':1,'letter':'a','symbol':'$'},{'number':2,'letter':'b','symbol':'%'},{'number':3,'letter':'c','symbol':'^'}]

Ответы [ 4 ]

1 голос
/ 22 сентября 2019

Вот один из способов сделать это

[{'number': n, 'letter': l} for n, l in zip(num_dict['number'], lett_dict['letter'])]
1 голос
/ 22 сентября 2019

Самый питонический способ, который я могу придумать, - это использовать понимание списка:

[{'number':n, 'letter':l} for n,l in zip(list(num_dict.values())[0], list(lett_dict.values())[0])]

zip используется для возврата комбинированных значений из обоих циклов, а [0] используется потому, что когдапреобразовывая значения dict в список, он возвращает список списка, например, [['a', 'b', 'c']], поэтому [0] использовался, чтобы получить только внутренний список, остальная часть кажется очевидной.

0 голосов
/ 22 сентября 2019

Я буду честен, я понятия не имею, что на практике означает «питон».

Вы приводите два разных примера одной и той же основной проблемы.Если вы хотите решение общего назначения, то вспомогательная функция может быть в порядке.

from typing import *

def zip_dict(*dicts: Dict[str, Iterable[Any]],
        keys: Optional[Iterable[str]] = None
    ) -> Iterable[Dict[str, Any]]:
        use_keys = keys if keys is not None else list(map(lambda d: next(iter(d.keys())), dicts))
        indexed_dicts = {k: dicts[i][k] for i, k in enumerate(use_keys)}
        ret_length = len(dicts[0][use_keys[0]])
        return[
            dict((k, indexed_dicts[k][i]) for k in use_keys)
            for i in range(ret_length)
        ]

#test it out
from pprint import pprint

test_data = {'number': [1, 2, 3], 'letter': ['a', 'b', 'c'],'symbol':['$','%','^']}

first_test = zip_dict({'number': test_data['number']}, {'letter': test_data['letter']})
pprint(first_test)

second_test = zip_dict(test_data, test_data, test_data, keys = ['number', 'letter','symbol'])
pprint(second_test)

печатает:

[{'letter': 'a', 'number': 1},
 {'letter': 'b', 'number': 2},
 {'letter': 'c', 'number': 3}]
[{'letter': 'a', 'number': 1, 'symbol': '$'},
 {'letter': 'b', 'number': 2, 'symbol': '%'},
 {'letter': 'c', 'number': 3, 'symbol': '^'}]

Вы заметите, что я не пытался предотвратитьэта функция выдает ошибки или указывает, как она должна обрабатывать «странные» данные.Я не знаю, каков ваш контекст;если вход «должен» всегда иметь правильную форму, то это, вероятно, хорошо.

0 голосов
/ 22 сентября 2019

после некоторого удара головой:

>>> d = {'number': [1, 2, 3], 'letter': ['a', 'b', 'c'],'symbol':['$','%','^']}

>>> [dict(zip(d.keys(), v)) for v in zip(*(d[k] for k in d.keys()))]

результат:

[{'number': 1, 'letter': 'a', 'symbol': '$'},
 {'number': 2, 'letter': 'b', 'symbol': '%'},
 {'number': 3, 'letter': 'c', 'symbol': '^'}]
...