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

use*_*024 6 python csv dictionary list

我是 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)})]
Run Code Online (Sandbox Code Playgroud)

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

test_file = ()
length = len(l[0])

with open('test1.csv', 'w', encoding = 'utf-8') as test_file:
    csv_writer = csv.writer(test_file, delimiter=',')
    for y in range(length):
        csv_writer.writerow([x[y] for x in l])
Run Code Online (Sandbox Code Playgroud)

它使列表中的最后一个元素,即字典,在输出文件中仅是一个字符串:

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)}
Run Code Online (Sandbox Code Playgroud)

这使得对最后一项中的值进行任何操作都无法进行。

我试图展平嵌套字典,所以我只会得到一个简单的列表,但结果不会保留项目之间的关系。我需要的是拆分字典并得到一个看起来像这样的输出:

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
Run Code Online (Sandbox Code Playgroud)

我的意思有点像这样,因为我不致力于这种格式,而是认为字典的层次关系不会在输出文件中丢失。有没有办法做到这一点?我对 python 真的很陌生,感谢任何帮助。谢谢!

TkT*_*ech 1

假设您必须将其存储在 CSV 中,字典中每项一行一行,以下显示了您如何写入和读取它。如果您有大量数据,这既不高效也不是最佳的,因为它会在每一行中重复数据,但它会压缩得很好。

#!/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)
Run Code Online (Sandbox Code Playgroud)