Чтение из текстового файла с именованными записями - PullRequest
0 голосов
/ 23 октября 2018

У меня проблема.У меня был список, состоящий из именованных кортежей.Я написал этот список в файл .txt.Теперь я хочу прочитать это обратно.Здесь я узнал, что json рекомендуется предварительно преобразовать и сохранить.Но мне нужно решение для моего уже сохраненного файла.Мой текстовый файл выглядит следующим образом:

file.txt:

[Hello(i=0, time=0, x=0, y=0), Hello(i=0, time=0, x=0, y=0),...]
[Hello(i=1, time=0, x=0, y=0), Hello(i=0, time=0, x=0, y=0),...]
[Hello(i=2, time=0, x=0, y=0), Hello(i=0, time=0, x=0, y=0),...]
[Hello(i=3, time=0, x=0, y=0), Hello(i=0, time=0, x=0, y=0),...]

Если я использую метод split, он почти такой же, как я хочу, но ожидаемый как строки:

lines = input_data.split('\n')
lines
['[Hello(i=0, time=0, x=0, y=0), Hello(i=0, time=0, x=0, y=0),...]','[Hello(i=1,...),...],...]']

Спасибоочень много, ребята!

Ответы [ 2 ]

0 голосов
/ 23 октября 2018

Вам нужно будет проанализировать ваш файл как текст и извлечь информацию, используя методы обработки текста.

Вы можете использовать регулярное выражение здесь:

import re

hello_pattern = re.compile(r'Hello\(i=(\d+), time=(\d+), x=(\d+), y=(\d+)\)')

Этот шаблон соответствует представлению ваших значений namedtuple и предоставляет вам доступ к числам для каждого значения, хотя и в виде строк:

>>> line = '[Hello(i=0, time=0, x=0, y=0), Hello(i=0, time=0, x=0, y=0),...]'
>>> hello_pattern.findall(sample)
[('0', '0', '0', '0'), ('0', '0', '0', '0')]

Затем вы можете снова преобразовать эти строки в целые числа и воссоздать экземпляры;для одной строки список будет выглядеть следующим образом:

[Hello(*map(int, match)) for match in hello_pattern.findall(line)]

и демонстрация этого в той же строке:

>>> from collections import namedtuple
>>> Hello = namedtuple('Hello', 'i time x y')
>>> [Hello(*map(int, match)) for match in hello_pattern.findall(sample)]
[Hello(i=0, time=0, x=0, y=0), Hello(i=0, time=0, x=0, y=0)]

Таким образом, полное решение будет:

import re
from collections import namedtuple

Hello = namedtuple('Hello', 'i time x y')  # or import your own ready definition
hello_pattern = re.compile(r'Hello\(i=(\d+), time=(\d+), x=(\d+), y=(\d+)\)')

data = []
with open('file.txt') as inputfile:
    for line in inputfile:
        recovered = [
            Hello(*map(int, match))
            for match in hello_pattern.findall(line)
        ]
        data.append(recovered)
0 голосов
/ 23 октября 2018

Как бы мне не хотелось продвигать eval(), это должен быть один из тех редких случаев, когда любое альтернативное решение еще хуже.

line = "[Hello(i=3, time=0, x=0, y=0), Hello(i=0, time=0, x=0, y=0)]"
# Original definition, I assume
Hello = namedtuple('Hello', ['i','time','x','y'])
data = eval(line)
#[Hello(i=3, time=0, x=0, y=0), Hello(i=0, time=0, x=0, y=0)]

NB Не следует использовать eval в любой ситуации, когда прочитанные вами данные ранее не создавались и не сохранялись вами .

...