Python 3:转换CSV

2024-05-15 22:55:23 发布

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

我的csv文件是这样的

1,no,apple,water
2,,grape,
3,yes,,coke
4,no,orange,water
5,no,,water

里面有些空白

我想把这个文件转换成字典列表,应该是

[{'id': '1', 'yesno': 'no', 'fruit': 'apple', 'drink': 'water'}, 
{'id': '2', 'fruit': 'grape'}, 
{'id': '3', 'yesno': 'yes', 'drink': 'coke'}, 
{'id': '4', 'yesno': 'no', 'fruit': 'orange', 'drink': 'water'}, 
{'id': '5', 'yesno': 'no', 'drink': 'water'}]

但是,它回来了

[{'id': '1', 'yesno': 'no', 'fruit': 'apple', 'drink': 'water'}, 
{'id': '2', 'yesno': 'no', 'fruit': 'grape', 'drink': 'water'}, 
{'id': '3', 'yesno': 'yes', 'fruit': 'grape', 'drink': 'coke'}, 
{'id': '4', 'yesno': 'no', 'fruit': 'orange', 'drink': 'water'}, 
{'id': '5', 'yesno': 'no', 'fruit': 'orange', 'drink': 'water'}]

似乎空白值是用前一个字典

中复制的值填充的。

这是我的密码

import csv
def data(file):
    header = ['id', 'yesno', 'fruit', 'drink']
    list_data = []
    dict_record = {}
    var = 0
    csv_r = list(csv.reader(open(file)))
    while var < len(csv_r):
        for i in range(4): #since there are 4 fields
            if csv_r[var][i] != '':
                dict_record[header[i]] = csv_r[var][i]
        list_data.append(dict_record.copy())
        var = var + 1
    return(list_data)

Tags: csvnoidappledatavarlistyes
1条回答
网友
1楼 · 发布于 2024-05-15 22:55:23

Python附带了一个csv解析器,不要重新发明轮子:

In [1]: import csv

In [2]: with open('example.csv') as f:
   ...:     reader = csv.DictReader(f, fieldnames=['id', 'yesno', 'fruit', 'drink'])
   ...:     data = list(reader)
   ...:

In [3]: data
Out[3]:
[{'drink': 'water', 'fruit': 'apple', 'id': '1', 'yesno': 'no'},
 {'drink': '', 'fruit': 'grape', 'id': '2', 'yesno': ''},
 {'drink': 'coke', 'fruit': '', 'id': '3', 'yesno': 'yes'},
 {'drink': 'water', 'fruit': 'orange', 'id': '4', 'yesno': 'no'},
 {'drink': 'water', 'fruit': '', 'id': '5', 'yesno': 'no'}]

It seems like the blank values are filled with the copied one from the previous dictionary

没有以前的字典,基本上你的方法的问题是你一直重复使用同一个字典,所以旧的值总是存在的。只要用一本新字典:

In [6]: with open('example.csv') as f:
   ...:     data = []
   ...:     names = ['id', 'yesno', 'fruit', 'drink']
   ...:     for line in f:
   ...:         items = line.strip().split(',')
   ...:         data.append({k:v for k,v in zip(names, items)})
   ...:
   ...:

In [7]: data
Out[7]:
[{'drink': 'water', 'fruit': 'apple', 'id': '1', 'yesno': 'no'},
 {'drink': '', 'fruit': 'grape', 'id': '2', 'yesno': ''},
 {'drink': 'coke', 'fruit': '', 'id': '3', 'yesno': 'yes'},
 {'drink': 'water', 'fruit': 'orange', 'id': '4', 'yesno': 'no'},
 {'drink': 'water', 'fruit': '', 'id': '5', 'yesno': 'no'}]

如果你真的不想包含空字段,你可以这样做:

In [8]: with open('example.csv') as f:
   ...:     data = []
   ...:     names = ['id', 'yesno', 'fruit', 'drink']
   ...:     for line in f:
   ...:         items = line.strip().split(',')
   ...:         data.append({k:v for k,v in zip(names, items) if v})
   ...:

In [9]: data
Out[9]:
[{'drink': 'water', 'fruit': 'apple', 'id': '1', 'yesno': 'no'},
 {'fruit': 'grape', 'id': '2'},
 {'drink': 'coke', 'id': '3', 'yesno': 'yes'},
 {'drink': 'water', 'fruit': 'orange', 'id': '4', 'yesno': 'no'},
 {'drink': 'water', 'id': '5', 'yesno': 'no'}]

一般建议:当你可以轻松使用for循环时,不要使用while循环。文件对象是可iterable的,只需执行for line in f:,为此,请始终使用with语句来使用文件(即使用上下文管理器),并且不要具体化整件事,即不要执行list(csv.reader(open(file))),除非您确实需要一个行列表。另外,如果不需要的话,不要使用基于索引的循环,了解python中方便的迭代器,比如enumeratezip。你知道吗

即使更好,也不要重新发明轮子:

In [10]: with open('example.csv') as f:
    ...:     reader = csv.DictReader(f, fieldnames=['id', 'yesno', 'fruit', 'drink'])
    ...:     data = [{k:v for k,v in row.items() if v} for row in reader]
    ...:

In [11]: data
Out[11]:
[{'drink': 'water', 'fruit': 'apple', 'id': '1', 'yesno': 'no'},
 {'fruit': 'grape', 'id': '2'},
 {'drink': 'coke', 'id': '3', 'yesno': 'yes'},
 {'drink': 'water', 'fruit': 'orange', 'id': '4', 'yesno': 'no'},
 {'drink': 'water', 'id': '5', 'yesno': 'no'}]

相关问题 更多 >