如何将csv文件的内容读入一个类,其中每个csv行都是一个类实例

2024-10-01 13:37:59 发布

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

我是一个Python新手,我已经为一个课堂作业苦苦挣扎了好几天。我有一个csv文件,其中包含这样的数据:

id,latitude,longitude,city,label,yr1970,yr1975,yr1980,yr1985,yr1990,yr1995,yr2000,yr2005
1,35.6832085,139.8089447,Tokyo,Tokyo,23.3,26.61,28.55,30.3,32.53,33.59,34.45,35.62

这个文件中大约有40行,每行都包含一个世界城市的相关数据。如您所见,最上面一行是标题。我应该用Python创建一个类,并将csv文件读入该类,其中每一行都成为该类的一个实例。然后我将在一个列表中存储类实例。我已经能够创建一个存储所有数据的实例,但是我似乎不能为每一行创建一个实例(而且我显然不想手动创建)。在

到目前为止我得到的是:

^{pr2}$

同样,我对Python(以及一般的编码)还很陌生,我意识到这段代码并不好,但是我很难找到将csv文件读入Python类的技巧。在


Tags: 文件csv数据实例idcitylabeltokyo
3条回答

一些帮助您清理代码的提示:

  1. 而不是这样:

    self.yr1970
    

    定义一个列表来记录年份及其值:

    ^{pr2}$

    现在将此结构与每个城市配对:

    cities = [
        { 'city': 'Tokyo',     'years': tokyo_years },
        { 'city': 'Vancouver', 'years': vancouver_years },
        # ...
    ]
    
  2. 别窝得这么深。还有,下面的情况真的很奇怪:

    for row in cityList:
        if row != 'label':
            for row in cityList:
    

    你在某物上循环,然后又在它上面循环,而你在它上面循环。。。!

  3. 类属于顶层。这意味着class前面应该有0个空格。在

             class City:
    

    应该是:

    class City:
    

我提到这一切的原因是,试图进一步处理混乱的代码只会导致更混乱的代码。:)尝试通过以下方式改进当前代码:

  1. 使用数据结构(列表、字典)。在
  2. 将嵌套代码的级别限制为最多2级(请考虑使用函数来帮助您)
  3. 把课程放在顶层。在

如果您的数据只是一个不可变的记录,请使用^{}

>>> from collections import namedtuple

>>> City = namedtuple('City', 'lat lon cityName label '
...                   'yr1970 yr1975 yr1980 yr1985 yr1990 yr1995 yr2000 yr2005 yr2010')

您可以在不需要第一个值的情况下对行进行切片,并使用*对其进行解压缩:

^{pr2}$

只需将此对象添加到城市列表中,而不是将所有属性都添加到列表中:

>>> cities.append(city)

将其与列表整合在一起,筛选出标签行:

import csv
from collections import namedtuple

City = namedtuple('City',
                  'lat lon cityName label '
                  'yr1970 yr1975 yr1980 yr1985 yr1990 yr1995 yr2000 yr2005 yr2010')

with open('filepath') as f:
    cities = [City(*row[1:]) for row in csv.reader(f)
              if row[0] != 'label']

你可以试试这个:

import csv
class City:
   def __init__(self, row, header):
        self.__dict__ = dict(zip(header, row))

data = list(csv.reader(open('file.csv')))
instances = [City(i, data[0]) for i in data[1:]]

但是,由于您提到有许多行,您可能需要为每个城市创建一个id,作为列表中的字符串表示:

^{pr2}$

您的输出将如下所示:

[city_1, city_2, city_3...]

任何属性都可以这样调用:

instances[1].latitude

关于您最近的评论,要通过城市名称访问城市属性,您可以稍微重组instances

instances = {a[3]:City(a, data[0], "city_{}".format(i+1)) for i, a in enumerate(data[1:])}

相关问题 更多 >