【问题标题】:Is there an easier way of transforming these python objects有没有更简单的方法来转换这些 python 对象
【发布时间】:2016-06-12 12:04:03
【问题描述】:

我想转换以下 python 输入:

[{'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 新手,我认为这可以使用列表推导以更简单的 Python 方式完成。谁能给个更好的答案?

【问题讨论】:

  • 我认为在您的输出中,在每个字典的最后一个键值对中,您的意思是 'paramN: valueN1'..'paramN':'valueN2'....'paramN':'valueNm'
  • 是的,感谢您的关注 :)

标签: python list dictionary transform list-comprehension


【解决方案1】:

首先将输入列表中的所有内容加入到one字典中;这样您就可以使用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'}]

【讨论】:

  • 谢谢,这正是我一直在寻找的,虽然我还不能完全理解。将仔细检查您的解释,直到清楚为止;)
【解决方案2】:
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)

这就是我想出的。不是很漂亮,但可以完成工作。此外,这要求值的长度始终相同,并且字典的第一个键和值是所需的参数和值。

编辑:忽略这个答案。 Martijn Pieters answer 更漂亮更易读!

【讨论】:

  • 请注意,dict.keys()dict.values() 上的索引仅适用于 Python 2;对于 Python 3,您必须将其替换为 next(iter(line))next(iter(line.items()))
猜你喜欢
  • 1970-01-01
  • 2019-07-21
  • 2021-08-11
  • 2012-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-14
相关资源
最近更新 更多