2

我有一个包含以下数据的纯文本文件:

id=1
name=Scott
occupation=Truck driver
age=23

id=2
name=Dave
occupation=Waiter
age=16

id=3
name=Susan
occupation=Computer programmer
age=29

我正在尝试找出在给定id字符串的情况下到达文件中任何点的最佳方法,然后抓取下面的行以提取数据以在我的程序中使用。我可以做类似的事情:

def get_person_by_id(id):
    file = open('rooms', 'r')
    for line in file:
        if ("id=" + id) in line:
            print(id + " found")

但我不确定我现在如何才能通过下一行并执行line.split("=")或类似操作来提取我可以使用我的程序的信息(放入列表或字典或其他任何内容)。任何指针?

4

7 回答 7

2

一种选择是将整个内容加载到内存中,这样您就不必每次都读取文件:

with open('rooms') as f:
    chunks = f.read().split('\n\n')

people_by_id = {}

for chunk in chunks:
    data = dict(row.split('=', 1) for row in chunk.split('\n'))
    people_by_id[data['id']] = data
    del data['id']

def get_person_by_id(id):
    return people_by_id.get(id)
于 2012-11-11T15:11:24.737 回答
1

找到正确的行后如何退出 for 循环:

def get_person_by_id(id):
    file = open('rooms', 'r')
    for line in file:
        if ("id=" + id) in line:
            print(id + " found")
            break
    #now you can continue processing your file:
    next_line = file.readline()
于 2012-11-11T15:12:15.583 回答
0

此解决方案对记录中的空行更加宽容。

def read_persons(it):
    person = dict()
    for l in it:
        try:
            k, v = l.strip('\n').split('=', 1)
        except ValueError:
            pass
        else:
            if k == 'id': # New record
                if person:
                    yield person
                    person = dict()
            person[k] = v
    if person:
        yield person
于 2012-11-11T16:37:46.533 回答
0

这是一个迭代解决方案。

objects = []
current_object = None
with open("info.txt", "rb") as f:
    for line in f:
        line = line.strip("\r\n")
        if not line:
            current_object = None
            continue
        if current_object is None:
            current_object = {}
            objects.append(current_object)
        key,_,value = line.partition('=')
        current_object[key] = value

print objects
于 2012-11-11T15:20:59.933 回答
0

获取该人的所有属性和值(id、姓名、职业、年龄等),直到找到一条 empy 行。

def get_person_by_id(id):
    person = {}
    file = open('rooms', 'r')
    for line in file:
        if found == True:
            if line.strip():
                attr, value = line.split("="):
            else:
                return person              
        elif ("id=" + id) in line:
            print(id + " found")
            found = True
            attr, value = line.split("=")
            person[attr] = value
    return person
于 2012-11-11T15:18:56.000 回答
0

Another example of an iterative parser:

from itertools import takewhile
def entries(f):
    e = {}
    def read_one():
        one = {}
        for line in takewhile(lambda x: '=' in x, f):
            key, val = line.strip().split('=')
            one[key] = val
        return one
    while True:
        one = read_one() 
        if not one:
            break
        else:
            e[one.pop('id')] = one
    return e

Example:

>>> with open('data.txt') as f:
..:    print entries(f)['2']
{'age': '16', 'occupation': 'Waiter', 'name': 'Dave'}
于 2012-11-11T15:29:04.407 回答
0

也许:

d = dict()

with open(filename) as f:
    for line in f:
        k,v = line.split('=')
        if 'id=' in line:
            d[v] = {}
        d[d.keys()[-1]][k] = v
于 2012-11-11T15:15:02.393 回答