简体   繁体   English

使用namedtuple条目从文本文件读取

[英]Reading from text-file with namedtuple entries

I have a problem. 我有个问题。 I had a list consisting of namedtuples. 我有一个包含命名元组的列表。 I wrote this list to a file.txt. 我将此列表写到了file.txt。 Now i want to read it back. 现在我想把它读回来。 I found out here that json is recommended for converting it beforehand and than saving it. 我在这里发现建议使用json事先进行转换,而不是保存。 But I need a solution for my already saved file. 但是我需要一个针对已经保存的文件的解决方案。 My textfile looks like this: 我的文本文件如下所示:

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),...]

If i use the split-method, it is almost as I want it to be, but as expected as strings: 如果我使用拆分方法,则几乎与我想要的一样,但是如预期的那样:

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,...),...],...]']

Thank you very much guys! 非常感谢你们!

You'll have to parse your file as text, and extract the information using text manipulation techniques. 您必须将文件解析为文本,然后使用文本处理技术提取信息。

You could use a regular expression here: 您可以在此处使用正则表达式

import re

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

This pattern matches the representation of your namedtuple values, and gives you access to the numbers for each values, albeit as strings: 此模式与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')]

You can then convert those strings to integers again and recreate the instances; 然后,您可以将这些字符串再次转换为整数并重新创建实例。 for a single line the list comprehension would be: 对于单行,列表理解为:

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

and a demo of this on the same 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)]

So the complete solution would be: 因此,完整的解决方案是:

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)

As much as I hate promoting eval() , this must be one of those rare cases when any alternative solution is even worse. 尽管我不喜欢推广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 You should not use eval in any situation when the data that you read was not previously produced and saved by yourself . 注意:在任何情况下,当您以前都不是自己生成和保存读取的数据时,就不要使用eval

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM