如何将带有嵌套字典的列表写入csv文件?

2024-10-01 09:40:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我是Python新手,尝试了所有我能想到的方法,但没有找到解决方法。 我有一个列表,其中最后一个条目是一个字典,有不同数量的键,看起来像。在

l = [('Apple', 1, 2, {'gala': (2, 1.0)}), 
('Grape ', 2, 4, {'malbec': (4, 0.25), 'merlot': (4, 0.75)}), 
('Pear', 4, 5, {'anjou': (5, 0.2), 'bartlet': (5, 0.4), 'seckel': (5, 0.2)}), 
('Berry', 5, 5, {'blueberry': (5, 0.2), 'blackberry': (5, 0.2), 'straw': (5, 0.2)})]

当我试图从当前列表中写入.csv文件时,我使用了:

^{pr2}$

它使列表中的最后一个元素dictionary在输出文件中仅为一个字符串:

Apple   1   2   {'gala': (2, 1.0)}
Grape   2   4   {'malbec': (4, 0.25), 'merlot': (4, 0.75)}
Pear    4   5   {'anjou': (5, 0.2), 'bartlet': (5, 0.4), 'seckel': (5, 0.2), 'bosc': (5, 0.2)}
Berry   5   5   {'blueberry': (5, 0.2), 'blackberry': (5, 0.2), 'straw': (5, 0.2)}

这使得在最后一项内的任何操作都不可能。在

我试图将嵌套的字典展平,以便只得到一个简单的列表,但是结果没有保留项之间的关系。我需要的是拆分字典,并生成如下所示的输出:

Apple   1   2   gala        2   1.0
Grape   2   4   malbec  4   0.25
            merlot      4   0.75
Pear    4   5   anjou       5   0.2
            bartlet     5   0.4
            seckel      5   0.2
            bosc        5   0.2
Berry   5   5   blueberry   5   0.2
            blackberry  5   0.2
            straw       5   0.2

我的意思是有点像这样,因为我并不致力于这种格式,而是坚持这样一个思想:字典的层次关系不会在输出文件中丢失。有办法吗?我对python非常陌生,非常感谢您的帮助。谢谢!在


Tags: apple列表字典pearberryblueberrymerlotgala
3条回答

假设您必须将它存储在一个CSV中,dict中的每一项都有一行,下面将展示如何编写和读取它。如果您有大量的数据,这不是高效的,也不是最佳的,因为它在每一行重复数据,但是它可以很好地压缩。在

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""csv_dict.py
"""
import csv
import pprint
from collections import namedtuple


Row = namedtuple('Row', [
    'name',
    'value_1',
    'value_2',
    'extra_name',
    'extra_value_1',
    'extra_value_2'
])


l = [
    ('Apple', 1, 2, {'gala': (2, 1.0)}),
    ('Grape ', 2, 4, {'malbec': (4, 0.25), 'merlot': (4, 0.75)}),
    ('Pear', 4, 5, {
        'anjou': (5, 0.2),
        'bartlet': (5, 0.4),
        'seckel': (5, 0.2)}
    ),
    ('Berry', 5, 5, {
        'blueberry': (5, 0.2),
        'blackberry': (5, 0.2),
        'straw': (5, 0.2)
    })
]

print('List before writing: ')
pprint.pprint(l)

# Writing the data.
with open('test1.csv', 'wb') as fout:
    writer = csv.writer(fout)

    for row in l:
        for k, v in row[3].iteritems():
            writer.writerow(row[0:3] + (k,) + v)

# Reading the data.
format_extra = lambda row: (int(row.extra_value_1), float(row.extra_value_2))

with open('test1.csv', 'rU') as fin:
    reader = csv.reader(fin)

    ll = []
    hl = {}

    for row in (Row(*r) for r in reader):
        if row.name in hl:
            ll[hl[row.name]][3][row.extra_name] = format_extra(row)
            continue

        ll.append(row[0:3] + ({
            row.extra_name: format_extra(row)
        },))
        hl[row.name] = len(ll) - 1

    pprint.pprint(ll)

如果您坚持使用CSV/TSV,您应该记住它是表的一种表示,但是您希望它看起来像一个结构化文件(XML/JSON/YAML)。我建议使用CSV/TSV将数据存储为关系表,否则您可能会遇到一些混乱的输出。在您的情况下,选择for的选项将输出如下:

标题:

SuperSpecieName,SpecieName,Value1,Value2

数据:

^{pr2}$

看起来你很亲密。有几点——您不需要初始化test_file,您可以将length放入迭代器中。在

如果我写这个到csv,我可能会用

with open('test1.csv', 'w', encoding = 'utf-8') as test_file:
  for row in l:
    species_data = row[:3]
    for subspecies, subspecies_data in row[4].iter_items():
      write_row = species_data + [subspecies] + list(subspecies_data)
      test_file.write(','.join([str(j) for j in write_row]))

当然,如果这是一个大列表,或者如果您非常关注重复信息,您可以进行一些优化。在

相关问题 更多 >