0

person.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

我希望将构造函数中的爱好打包到列表中:

(...)
Birth Year: 1990, Hobby: ['tenis','piano'], Surname: Smith, Firstname: John, 
['tenis', 'piano']
Birth Year: 1988, Hobby: ['surfing','art'], Surname: Josh, Firstname: Andrew, 
['surfing', 'art']
4

3 回答 3

1

当您阅读其中的行时,您需要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
于 2013-07-24T00:27:35.593 回答
0

我解决了它如下。马吕斯你的回答是一种暗示。

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 新手,所以任何关于更好的代码实践的建议都将不胜感激。

于 2013-07-24T01:07:57.630 回答
0
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
于 2013-07-24T00:26:57.183 回答