Python - 将文件导入到命名元组中

6

最近我有一个关于数据类型的问题。
从那时起,我一直在尝试使用NamedTuples(有更多或更少的成功)。

我目前的问题:
- 如何将文件中的行导入到新元组中,
- 如何将用空格/制表符(/任何其他分隔符)分隔的值导入到元组的特定部分中?

例如:

Monday  8:00    10:00   ETR_28135   lh1n1522    Computer science    1     
Tuesday 12:00   14:00   ETR_28134   lh1n1544    Geography EA    1  

第一行应该放在tuple[0]中。第一个数据:tuple[0].day; 第二个:tuple[0].start; ...以此类推。
当新的一行开始时(即两个TAB(\t)),开始一个新的元组,例如tuple[1]。

我用这个来分隔数据:

with open(Filename) as f:
    for line in f:
        rawData = line.strip().split('\t')  

还有一部分逻辑还没有完成(填充元组)。

我知道,这个问题和最近的一个问题都非常基础。但是,我希望这些问题也能帮助其他人。如果你觉得这不是一个真正的问题,或者太简单了,等等,请投票关闭。谢谢您的理解。

3个回答

12
这种数据库文件被称为逗号分隔值,即使它们并不是真正由逗号分隔。Python有一个方便的库叫做csv,可以让您轻松地读取这种文件。
以下是稍微修改过的文档示例
csv.register_dialect('mycsv', delimiter='\t', quoting=csv.QUOTE_NONE)
with open(filename, 'rb') as f:
    reader = csv.reader(f, 'mycsv')

通常你需要逐行处理。如果需要将整个文件转换为元组,则:
t = tuple(reader)

编辑

如果您需要通过名称访问字段,可以使用cvs.DictReader,但我不知道它的工作原理,因为我无法在这里进行测试。

编辑2

看看namedtuples是什么,我有点过时了。这里有一个很好的例子,说明如何使用命名元组与csv模块一起使用:

EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade')

import csv
for line in csv.reader(open("employees.csv", "rb")):
    emp = EmployeeRecord._make(line)
    print emp.name, emp.title

坦白地说,这篇文章中的读取器代码还不错。问题是关于命名元组的,而这个答案有点偏离了主题。 - 9000
命名元组部分在这里并没有真正起作用,但是我正在努力找出问题所在。 - Apache
@Shiki:很奇怪。一旦你有了一个读取器并创建了一个命名元组类,只需迭代读取器并为每行调用“_make”。 - mg.
我知道你已经做了很多,但你能更具体一些吗?你在这里怎么做到的? - Apache
@Shiki:我甚至不知道你在使用namedtuple时遇到了什么问题,你是否从collections中导入了它? from collections import namedtuple。然后创建元组子类:MyRecord = namedtuple('MyRecord', ['day,', 'start', 'and so on', '...']),然后只需调用其_make方法:for line in reader: line = MyRecord._make(line); print line.day, line.start - mg.

3
这是一种简洁的做法。 首先声明行项目的类:
fields = "dow", "open_time", "close _time", "code", "foo", "subject", "bar"
Item = namedtuple('Item', " ".join(fields)) 

下一部分在您的循环内部。
# this is what your raw data looks like after the split:
#raw_data = ['Monday', '8:00', '10:00', 'ETR_28135', 'lh1n1522', 'Computer science', '1']
data_tuple = Item(**dict(zip(fields, raw_data)))

现在慢慢来:
zip(fields, raw_data)创建一对列表,如[("dow", "Monday"), ("open_time", "8:00"),..]
然后dict()将其转换为字典,如{"dow": "Monday", "open_time": "8:00", ..}
接着**将此字典解释为Item构造函数的一堆关键字参数,相当于Item(dow="Monday", open_time="8:00",..)。
所以您的items是具有所有值为字符串的命名元组。
编辑:
如果字段的顺序不会改变,那么您可以更轻松地完成这项任务:
data_tuple = Item(*raw_data)

这是利用文件中字段的顺序和Item定义中参数的顺序匹配的事实。

3
如果你想使用NamedTuple,你可以使用Python文档中给出的稍有修改的示例:
MyRecord = namedtuple('MyRecord', 'Weekday, start, end, code1, code2, title, whatever')

import csv
for rec in map(MyRecord._make, csv.reader(open("mycsv.csv", "rb"), delimiter='\t')):
    print rec.weekday
    print rec.title
    # etc...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接