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

1つのオプションは、すべてをメモリにロードすることです。これにより、毎回ファイルを読み取る必要がなくなります。

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

エンピーラインが見つかるまで、その人のすべての属性と値(ID、名前、職業、年齢など)を取得します

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

多分:

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 に答える
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

反復パーサーの別の例:

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

例:

>>> with open('data.txt') as f:
..:    print entries(f)['2']
{'age': '16', 'occupation': 'Waiter', 'name': 'Dave'}
于 2012-11-11T15:29:04.407 に答える
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 に答える