将3个列表解析为python中的字典列表
Posted
技术标签:
【中文标题】将3个列表解析为python中的字典列表【英文标题】:parsing 3 lists into list of dictionaries in python 【发布时间】:2021-12-30 23:01:31 【问题描述】:我正在逐行解析 csv。一行中有 3 列需要将每列拆分为列表,然后在列表中组合成字典。每列内的数据由两个管道分隔:||
传入数据:
按钮,点击,id 选择1 ||选择2 ||选择 3,正确 ||错误 ||错误,选择 1 id||选择 2 id ||选择 3 id
数据已通过 csv DiskReader 导入,脚本中的每一行都是有序字典,如下所示:('buttons','choice 1 || choice 2 || choice 3'),
('clicked', 'TRUE || FALSE || FALSE'),
('id','choice 1 id|| choice 2 id || choice 3 id'),
编辑添加: input 有很多不应该包含的列。此步骤仅包含这 3 列。
即正在处理的行的示例输出
print(data[0])
OrderedDict([
('pathId', 'test_id'),
('stepId', ''),
('nodeId', 'ROOT'),
('responseId', 'test_response'),
('responseUuid', ''),
('type', ''),
('language', 'en-US'),
('buttons','choice 1 || choice 2 || choice 3'),
('clicked', 'TRUE || FALSE || FALSE'),
('id','choice 1 id|| choice 2 id || choice 3 id'),
('state', 'resolved'),
('flags', 'accepted')])
实际的列数是动态的且不可预测的。但在包含 buttons
、clicked
和 id
值的行中将需要此处理。END EDIT
预期输出需要:
buttonChoices =
[
"button": "choice 1",
"clicked": true,
"id": "choice 1 id"
,
"button": "choice 2",
"clicked": false,
"id": "choice 2 id"
,
"button": "choice 3",
"clicked": false,
"id": "choice 3 id"
]
我事先不知道列表中有多少个值,但是这 3 列中的值是相同的
现在我有:
for row in data:
buttonChoices = []
buttonText = row['button'].split('||')
buttonClicked = row['clicked'].split('||')
buttonId = row['id'].split('||')
但卡住了下一步
【问题讨论】:
为什么您的 CSV 看起来像这样?为什么每个按钮点击事件没有单独的一行数据? 就是这样...所有相关记录都排成一行 【参考方案1】:您可以使用 zip 将值 3 x 3 组合并将它们与键相关联:
data = dict([ ('buttons','choice 1 || choice 2 || choice 3'),
('clicked', 'TRUE || FALSE || FALSE'),
('id','choice 1 id|| choice 2 id || choice 3 id')])
buttonChoices = [ dict(zip(data,map(str.strip,values)))
for values in zip(*(v.split("||") for v in data.values())) ]
print(buttonChoices)
['buttons': 'choice 1', 'clicked': 'TRUE', 'id': 'choice 1 id',
'buttons': 'choice 2', 'clicked': 'FALSE', 'id': 'choice 2 id',
'buttons': 'choice 3', 'clicked': 'FALSE', 'id': 'choice 3 id']
注意:我在其中添加了一个 map(str.strip,...) 来清理混乱的字符串分隔,但如果您的实际数据格式正确,则不需要它
为了概括这一点,您可以定义输入键和输出键以根据需要进行过滤和重命名:
inKeys = ('buttons','clicked','id')
outKeys = ('button','clicked','id')
buttonChoices = [ dict(zip(outKeys,map(str.strip,values)))
for values in zip(*(data[k].split("||") for k in inKeys)) ]
print(buttonChoices)
['button': 'choice 1', 'clicked': 'TRUE', 'id': 'choice 1 id',
'button': 'choice 2', 'clicked': 'FALSE', 'id': 'choice 2 id',
'button': 'choice 3', 'clicked': 'FALSE', 'id': 'choice 3 id']
【讨论】:
我认为如果“数据”中没有其他字典值,这可行,但原始 csv 中有更多列不需要添加到此部分。 (他们得到单独的处理)有没有办法通过键限制data
中的内容?像熊猫data['buttons', 'clicked', 'id]
?
这应该是可能的,但我需要查看源数据和预期排除的示例(在您的问题中,而不是在评论中)才能正确回答。
我在问题中添加了编辑
我明白了,我添加到答案中的“通用”版本应该涵盖了这一点。【参考方案2】:
如果我正确理解了这个问题,那么这应该可以工作。
button_choices = []
for row in data:
button_texts = row['button'].split('||')
button_clickeds = row['clicked'].split('||')
button_ids = row['id'].split('||')
for button_text, button_clicked, button_id in zip(button_texts, button_clickeds, button_ids):
button_choices.append(
'button': button_text,
'clicked': button_clicked,
'id': button_id
)
【讨论】:
以上是关于将3个列表解析为python中的字典列表的主要内容,如果未能解决你的问题,请参考以下文章