CSV DictReader,如何强制“”中的部分作为列表而不是字符串读取
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CSV DictReader,如何强制“”中的部分作为列表而不是字符串读取相关的知识,希望对你有一定的参考价值。
persons.CSV文件看起来像:
Firstname,Surname,Birth Year,Hobby
John,Smith,1990,"tenis,piano"
Andrew,Josh,1988,"surfing,art"
我希望在程序爱好中将表示为列表而不是字符串。我该如何强制使用该DictReader?
我使用的python代码如下:
import csv
class Person(object):
extPerson = []
counter = 0
def __init__(self, **args):
for k, v in args.items():
setattr(self, k, v)
Person.counter += 1
Person.extPerson.append(self)
def __str__(self):
s=""
for k,v in self.__dict__.items():
s+=k+": "+v+", "
return s
csvdr = csv.DictReader(open('persons.csv'))
for p in csvdr:
print p
Person(**p)
for p in Person.extPerson:
print p
print p.Hobby
输出如下:
{'Birth Year': '1990', 'Hobby': 'tenis,piano', 'Surname': 'Smith', 'Firstname': 'John'}
{'Birth Year': '1988', 'Hobby': 'surfing,art', 'Surname': 'Josh', 'Firstname': 'Andrew'}
Birth Year: 1990, Hobby: tenis,piano, Surname: Smith, Firstname: John,
tenis,piano
Birth Year: 1988, Hobby: surfing,art, Surname: Josh, Firstname: Andrew,
surfing,art
我想将构造函数中的hobbys打包到列表中:
(...)
Birth Year: 1990, Hobby: ['tenis','piano'], Surname: Smith, Firstname: John,
['tenis', 'piano']
Birth Year: 1988, Hobby: ['surfing','art'], Surname: Josh, Firstname: Andrew,
['surfing', 'art']
答案
当你正在读取行时,你需要split()
的爱好字段:
one_row = {'Birth Year': '1990', 'Hobby': 'tenis,piano', 'Surname': 'Smith', 'Firstname': 'John'}
one_row['Hobby'] = one_row['Hobby'].split(',')
one_row
Out[7]:
{'Birth Year': '1990',
'Firstname': 'John',
'Hobby': ['tenis', 'piano'],
'Surname': 'Smith'}
在您当前的代码中,这将在这里:
for p in csvdr:
p['Hobby'] = p['Hobby'].split(',')
print p
Person(**p)
您当前的__str__
方法不适用于列表,但您只需要进行一些小修改即可 - 使用str
将列表值转换为字符串,并且字符串值不受影响:
def __str__(self):
s=""
for k,v in self.__dict__.items():
s += k + ": " + str(v) + ", "
return s
另一答案
class MyDictReader(csv.DictReader):
def next(self):
if self.line_num == 0:
# Used only for its side effect.
self.fieldnames
row = self.reader.next()
self.line_num = self.reader.line_num
# unlike the basic reader, we prefer not to return blanks,
# because we will typically wind up with a dict full of None
# values
while row == []:
row = self.reader.next()
row = map(lambda x:x.split(",") if "," in x else x,row)
d = dict(zip(self.fieldnames, row))
lf = len(self.fieldnames)
lr = len(row)
if lf < lr:
d[self.restkey] = row[lf:]
elif lf > lr:
for key in self.fieldnames[lr:]:
d[key] = self.restval
return d
另一答案
我解决了它如下。马吕斯你的回答是一种暗示。
for p in csvdr:
#p["Hobby"] = p["Hobby"].split(',') not working, TypeError: cannot concatenate 'str' and 'list' objects
l=p["Hobby"].split(',') #this will be list
p["Hobby"]=l #let key show on value being list
print p
Person(**p)
我们可以确保:
for p in Person.extPerson:
print p
print p.Hobby
print type(p.Hobby)
结果是:
{'Birth Year': '1990', 'Hobby': ['tenis', 'piano'], 'Surname': 'Smith', 'Firstname': 'John'}
{'Birth Year': '1988', 'Hobby': ['surfing', 'art'], 'Surname': 'Josh', 'Firstname': 'Andrew'}
Birth Year: 1990, Hobby: ['tenis', 'piano']Surname: Smith, Firstname: John,
['tenis', 'piano']
<type 'list'>
Birth Year: 1988, Hobby: ['surfing', 'art']Surname: Josh, Firstname: Andrew,
['surfing', 'art']
<type 'list'>
[Finished in 0.1s]
顺便说一下str需要修改检查类型,并适当处理列表:
def __str__(self):
s=""
for k,v in self.__dict__.items():
if type(v) is not list:
s+=k+": "+v+", "
else:
s+=k+": "+str(v)
return s
我是python的新手,所以对于更好的代码实践的任何建议将不胜感激。
以上是关于CSV DictReader,如何强制“”中的部分作为列表而不是字符串读取的主要内容,如果未能解决你的问题,请参考以下文章
Python 3.2 在 csv.DictReader 中跳过一行
如何使用 csv.DictReader 在 django 中上传和读取 csv 文件?