开发者

Python - Import file into NamedTuple

Recently I had a question regarding data types.

Since then, I've been trying to use NamedTuples (with more or less success).

My problem currently:

- How to import the lines from a file to new tuples,

- How to import the values separated with space/tab(/whatever) into a given part of the tuple?

Like:

Monday  8:00    10:00   ETR_28135   lh1n1522    Computer science    1     
Tuesday 12:0开发者_Python百科0   14:00   ETR_28134   lh1n1544    Geography EA    1  

First line should go into tuple[0]. First data: tuple[0].day; second: tuple[0].start; ..and so on.

And when the new line starts (that's two TAB (\t), start a new tuple, like tuple[1]).

I use this to separate the data:

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

And the rest of the logic is still missing (the filling up of the tuples).

(I know. This question, and the recent one are really low-level ones. However, hope these will help others too. If you feel like it's not a real question, too simple to be a question, etc etc, just vote to close. Thank you for your understanding.)


Such database files are called comma separated values even though they are not really separated by commas. Python has a handy library called csv that lets you easily read such files

Here is a slightly modified example from the docs

csv.register_dialect('mycsv', delimiter='\t', quoting=csv.QUOTE_NONE)
with open(filename, 'rb') as f:
    reader = csv.reader(f, 'mycsv')

Usually you work one line at a time. If you need the whole file in a tuple then:

t = tuple(reader)

EDIT

If you need to access fields by name you could use cvs.DictReader, but I don't know how exactly that works and I could not test it here.

EDIT 2

Looking at what namedtuples are, I'm a bit outdated. There is a nice example on how namedtuple could work with the csv module:

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


If you want to use a NamedTuple, you can use a slightly modified version of the example given in the Python documentation:

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


Here's a compact way of doing such things. First declare the class of line item:

fields = "dow", "open_time", "close _time", "code", "foo", "subject", "bar"
Item = namedtuple('Item', " ".join(fields)) 

The next part is inside your loop.

# 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)))

Now slowly:

  • zip(fields, raw_data) creates a list of pairs, like [("dow", "Monday"), ("open_time", "8:00"),..]
  • then dict() turns it into a dictionary, like {"dow": "Monday", "open_time": "8:00", ..}
  • then ** interprets this dictionary as a bunch of keyword parameters to Item constructor, an equivalent of Item(dow="Monday", open_time="8:00",..).

So your items are named tuples, with all values being strings.

Edit:

If order of fields is not going to change, you can do it far easier:

data_tuple = Item(*raw_data)

This uses the fact that order of fields in the file and order of parameters in Item definition match.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜