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 文件?

从 csv.DictReader 中查找字典值

如何复制python DictReader对象?

在 python 中使用 csv.DictReader 进行数据类型转换的最快方法

带有 UTF-8 数据的 Python CSV DictReader