当行内容是相关键的键值(每列的标题)时,如何用python在csv中编写嵌套字典?

Posted

技术标签:

【中文标题】当行内容是相关键的键值(每列的标题)时,如何用python在csv中编写嵌套字典?【英文标题】:How to write nested dictionary in csv with python when the row contents are key values of related key (the header of each column)? 【发布时间】:2021-09-22 16:57:05 【问题描述】:

我有一本名为“输出”的字典,其中嵌套了一些其他字典,如下所示:

>>> output.keys() 
dict_keys(['posts', 'totalResults', 'moreResultsAvailable', 'next', 'requestsLeft', 'warnings'])

>>> output['posts'][0].keys() 
dict_keys(['thread', 'uuid', 'url', 'ord_in_thread', 'parent_url', 'author', 'published', 'title','text', 'highlightText', 'highlightTitle', 'highlightThreadTitle', 'language', 'external_links', 'external_images', 'entities', 'rating', 'crawled', 'updated'])

>>> output['posts'][0]['thread'].keys() 
dict_keys(['uuid', 'url', 'site_full', 'site', 'site_section', 'site_categories', 'section_title', 'title', 'title_full', 'published', 'replies_count', 'participants_count', 'site_type', 'country', 'spam_score', 'main_image', 'performance_score', 'domain_rank', 'reach', 'social'])

>>> output['posts'][0]['thread']['social'].keys() 
dict_keys(['facebook', 'gplus', 'pinterest', 'linkedin', 'stumbledupon', 'vk'])

我想制作一个 csv 文件,其中包含来自 output['posts'][0]output['posts'][0]['thread ']output['posts'][0]['thread']['social'] 将相关值作为每行内容,我想出了以下代码:

post_keys = output['posts'][0].keys()
post_thread_keys = output['posts'][0]['thread'].keys()
social_keys = output['posts'][0]['thread']['social'].keys()

with open('file.csv', 'w', encoding='utf-8') as csvfile:
    writer = csv.DictWriter(csvfile, fieldnames=post_thread_keys)
    writer.writeheader()

    for i in range(len(output['posts'])):
         for key in output['posts'][i]['thread']:
            writer.writerow(output['posts'][i]['thread'])

它只适用于 "output['posts'][0]['thread']" 的第一级字典,不适用于其他内部人员,而且它的行数加倍现在是 200 而不是 100。

现在结果是这样的:

希望是这样的:

请查看我存储在谷歌驱动器上的输出文件以获得更切实的方法: file.csv

【问题讨论】:

包含字典的删节样本以获得更好的答案。 另外请附上您预期输出的样本。 我已经添加了当前输出的结果和想要的图像。 你能做到print(output) 并给我们一个输出的链接吗?你可以使用类似pastebin 我在驱动器上放了一个输出文件,请看一下。 【参考方案1】:

您需要一个函数来以您指定的格式创建子键。通过使用一个函数,它也可以被调用来给你额外列的列表 标题所需的名称。

当您添加 3 个子条目时,可以将它们从列中删除以避免重复(通过使用 .pop()

import webhoseio
import csv

def get_social_entries(social):
    social_entries = 

    for social_key, social_values in social.items():
        for key, value in social_values.items():
            social_entries[f'social_key_key'] = value
            
    return social_entries
        
    
    
# <<Get output here>>

csv_columns = []
 
first_post = output['posts'][0]

for key in first_post['thread']:
    csv_columns.append(key)
 
for key in first_post:
    if key not in ['entities', 'thread', 'social']:
        csv_columns.append(key)
 
for key in first_post['entities']:
    csv_columns.append(key)

csv_columns.extend(list(get_social_entries(first_post['thread']['social']).keys()))

with open('file.csv', 'w', encoding='utf-8', newline='') as csvfile:
    writer = csv.DictWriter(csvfile, fieldnames=csv_columns)
    writer.writeheader()
    
    for post in output['posts']:
        thread = post.pop('thread')
        entities = post.pop('entities')
        social = thread.pop('social')
        social_entries = get_social_entries(social)
        writer.writerow(post | thread | entities | social_entries)     # | operator needs Python 3.9

这假设您使用的是 Python 3.9,如果不是,您可以使用类似:

row = post
row.update(thread)
row.update(entities)
row.update(social_entries)
writer.writerow(row)

注意:添加newline='' 是为了删除输出中多余的空行。

您可以使用类似的方法来扩展entities

【讨论】:

感谢您的热心贡献,请看一下生成的 csv 文件,有 6 行额外,它们的填充列超过了更长的时间,对我来说它们是第 17,18 行, 24、25、86 和 87。 这是该 csv 文件的链接:drive.google.com/file/d/1BCVyW41H0Fbt9z7WKMKaGoka1HTOJUF1/… 我不确定我是否理解,该文件看起来不错。 CSV 文件不指定列的宽度。 text 列有时很宽,有时很长。如果这是一个问题,您可以在编写之前对其进行修改。例如将换行符转换为空格。如果您使用 Excel 来查看它,请确保从空白电子表格开始并使用 Data->From Text/CSV 使用 utf-8 编码导入它(不要双击文件) 是的,你是对的,打开它有缺陷是我的 ms office 问题。该代码运行良好。我非常感谢您的宝贵帮助和您在这方面所花费的时间。非常感谢!

以上是关于当行内容是相关键的键值(每列的标题)时,如何用python在csv中编写嵌套字典?的主要内容,如果未能解决你的问题,请参考以下文章

分布式、一致的键值存储系统在处理并发请求时如何返回最新键的基础知识?

编辑核心数据会产生错误,此类与键的键值编码不兼容

接口构建器问题:连接 IBOutlet 时,获取“此类与键的键值编码不兼容”

此类不是键的键值编码兼容的键

iOS/Facebook 登录错误:此类与键的键值编码不兼容

使用 Restkit 0.20 映射此类与键的键值编码不兼容