簡體   English   中英

如何使用嵌套字典將列表寫入csv文件?

[英]How to write a list with a nested dictionary to a csv file?

我是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文件時,我使用了:

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])

它使列表中的最后一個元素(字典)只是輸出文件中的一個字符串:

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的新手,感謝任何幫助。 謝謝!

假設您必須將其存儲在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)

好像你很親密。 幾點 - 您不需要初始化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]))

當然,如果它是一個大的列表,或者如果你非常擔心重復信息,你可以進行優化。

這是一個快速功能,我修改為采取列表,元組或字典並將其展平。 它將展平所有嵌套部件。

我修改了你的代碼並在python 2.7中測試過。 這應該生成您正在尋找的輸出:

def flatten(l):
'''
flattens a list, dict or tuple
'''
    ret = []
    for i in l:
        if isinstance(i, list) or isinstance(i, tuple):
            ret.extend(flatten(i))
        elif isinstance(i, dict):
            ret.extend(flatten(i.items()))
        else:
            ret.append(i)
    return ret

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)})]

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

with open('test1.csv', 'wb') as test_file:
    csv_writer = csv.writer(test_file, delimiter=',')
    for y in range(length):
        line = flatten(l[y])
        csv_writer.writerow([x for x in line])

如果你堅持使用CSV / TSV,你應該記住它是表的表示,但你希望它看起來像一個結構化文件(XML / JSON / YAML)。 我建議使用CSV / TSV將數據存儲為關系表,否則你可能會遇到一些混亂的輸出。 在您的情況下,選擇的選項將輸出如下:

標題:

SuperSpecieName,SpecieName,Value1,Value2

數據:

"",Apple,1,2
Apple,gala,2,1.0
"",Grape,2,4
Grape,malbec,4,0.25
Grape,merlot,4,0.75
...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM