2016-06-12 2 views
1

I`d хотел преобразовать следующий входной питона:Есть ли более простой способ преобразования этих объектов питона

[{'paramA': ['valA1','valA2','valA3','valA4']}, 
{'paramB': ['valB1','valB2','valB3','valB4']}, 
{'paramC': ['valC1','valC2','valC3','valC4']}, 
# ..........................................., 
{'paramN': ['valN1', 'valN2','valN3','valN4']}] 

В следующий вывод:

[{'paramA': 'valA1','paramB': 'valB1', 'paramC': 'valC1', ...,'paramN':'valN1' } 
{'paramA': 'valA2','paramB': 'valB2', 'paramC': 'valC2', ...,'paramN':'valN2' } 
{'paramA': 'valA3','paramB': 'valB3', 'paramC': 'valC3', ...,'paramN':'valN3' } 
{'paramA': 'valA4','paramB': 'valB4', 'paramC': 'valC4', ...,'paramN':'valN4' } ] 

Единственная функция, которую я мог придумать заключается в следующем:

def transformParams(inputParams): 
    res = [] 
    for i in inputParams: 
     for k,v in i.items(): 
      for ind, inv in enumerate(v): 
       if len(res) <= ind: 
        res.append({}) 
       res[ind][k] = inv 
    return res 

Я новичок в Python, и я думаю, что это может быть сделано более простым способом, используя вещий список понятий. Может ли кто-нибудь прийти с лучшим ответом?

+0

Я думаю, что на вашем выходе, при последних парах значений ключа каждого словаря, вы имеете в виду '' paramN: valueN1 '..' paramN ':' valueN2 '....' paramN ':' valueNm''? –

+0

Да, спасибо, что заметили :) –

ответ

4

Сначала соедините все в списке входных данных в один словарь; Таким образом, вы можете использовать zip() преобразовать все значения в строки, и вновь объединить, что с ключами:

try: 
    # use efficient Python 3 version in Python 2 
    from future_builtins import zip 
except ImportError: 
    # Python 3 
    pass 

combined = reduce(lambda d1, d2: dict(d1, **d2), inputlist) 
result = [dict(zip(combined, col)) for col in zip(*combined.values())] 

В zip() function паре до элементов из входных списков вместе, производя кортеж со всеми первыми элементами, то все второй и т. д. * в вызове zip(*list_of_lists) применяет все содержащиеся в нем последовательности (здесь все списки из значений объединенного словаря) в качестве отдельных аргументов, которые затем zip() затем переходят в пару. По существу это переносит строки в последовательности столбцов.

Эти последовательности столбцов затем повторно объединены с ключами (опять же с использованием zip() для создания сопряжения) для формирования выходных словарей.

Демо:

>>> inputlist = [ 
...  {'paramA': ['valA1','valA2','valA3','valA4']}, 
...  {'paramB': ['valB1','valB2','valB3','valB4']}, 
...  {'paramC': ['valC1','valC2','valC3','valC4']}, 
...  # ..........................................., 
...  {'paramN': ['valN1', 'valN2','valN3','valN4']}] 
>>> combined = reduce(lambda d1, d2: dict(d1, **d2), inputlist) 
>>> [dict(zip(combined, col)) for col in zip(*combined.values())] 
[{'paramN': 'valN1', 'paramC': 'valC1', 'paramB': 'valB1', 'paramA': 'valA1'}, {'paramN': 'valN2', 'paramC': 'valC2', 'paramB': 'valB2', 'paramA': 'valA2'}, {'paramN': 'valN3', 'paramC': 'valC3', 'paramB': 'valB3', 'paramA': 'valA3'}, {'paramN': 'valN4', 'paramC': 'valC4', 'paramB': 'valB4', 'paramA': 'valA4'}] 
>>> from pprint import pprint 
>>> pprint(_) 
[{'paramA': 'valA1', 'paramB': 'valB1', 'paramC': 'valC1', 'paramN': 'valN1'}, 
{'paramA': 'valA2', 'paramB': 'valB2', 'paramC': 'valC2', 'paramN': 'valN2'}, 
{'paramA': 'valA3', 'paramB': 'valB3', 'paramC': 'valC3', 'paramN': 'valN3'}, 
{'paramA': 'valA4', 'paramB': 'valB4', 'paramC': 'valC4', 'paramN': 'valN4'}] 
+0

Спасибо, это именно то, что я искал, хотя я пока не могу понять это полностью. Пересмотрите свое объяснение, пока оно не станет ясно;) –

1
l = [ 
    {"paramA": ["valA1","valA2","valA3","valA4"]}, 
    {"paramB": ["valB1","valB2","valB3","valB4"]}, 
    {"paramC": ["valC1","valC2","valC3","valC4"]}, 
] 

output = [dict([(line.keys()[0], line.values()[0][index]) for line in l]) for index in range(len(l[0].values()[0]))] 

print(output) 

Это то, что я придумал. Не очень красиво, но выполняет свою работу. Кроме того, для этого требуется, чтобы длина значений всегда была одинаковой, и первый ключ и значение словаря были требуемым параметром и значением val.

Редактировать: Игнорировать этот ответ. Martijn Pieters answer путь более красивый и читаемый!

+1

Обратите внимание, что индексирование на 'dict.keys()' и 'dict.values ​​()' работает только в Python 2; для Python 3 вам придется заменить это на 'next (iter (line))' и 'next (iter (line.items())). –

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