【问题标题】:parsing 3 lists into list of dictionaries in python将3个列表解析为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')])

实际的列数是动态的且不可预测的。但在包含 buttonsclickedid 值的行中将需要此处理。
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 看起来像这样?为什么每个按钮点击事件没有单独的一行数据?
  • 就是这样...所有相关记录都排成一行

标签: python ordereddictionary


【解决方案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
            })

【讨论】:

    猜你喜欢
    • 2018-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-04
    • 2014-10-07
    • 1970-01-01
    相关资源
    最近更新 更多