修改文件列表 - 正确的语法和文件格式?

时间:2018-03-19 02:05:31

标签: python

我目前有一个硬编码到我的python代码中的列表。随着它不断扩展,我想通过从文件中读取列表来使其更具动态性。我已阅读了许多关于如何做到这一点的文章,但在实践中我无法使其发挥作用。首先,这是现有硬编码列表的一个示例:

serverlist = []
serverlist.append(("abc.com", "abc"))
serverlist.append(("def.com", "def"))
serverlist.append(("hji.com", "hji"))

当我输入命令'print serverlist'时,输出如下所示,当我访问它时,我的列表工作正常:

[('abc.com', 'abc'), ('def.com', 'def'), ('hji.com', 'hji')]

现在我用以下内容替换了上面的代码:

serverlist = []
with open('/server.list', 'r') as f:
    serverlist = [line.rstrip('\n') for line in f]

server.list的内容为:

'abc.com', 'abc'
'def.com', 'def'
'hji.com', 'hji'

当我现在输入命令print serverlist时,输出如下所示:

["'abc.com', 'abc'", "'def.com', 'def'", "'hji.com', 'hji'"]

列表无法正常工作。那我究竟做错了什么?我是否正确读取文件或我是否正确格式化文件?或其他什么?

3 个答案:

答案 0 :(得分:1)

该文件的内容不会被解释为Python代码。当你读到line in f时,它是一个字符串;你文件中的引号,逗号等只是那些字符作为字符串的一部分。

如果要从字符串创建其他数据结构,则需要解析它。除非您指示,否则程序无法知道您希望将字符串"'abc.com', 'abc'"转换为元组('abc.com', 'abc')

这就是问题变得过于宽泛的问题"。

如果您控制文件内容,则可以简化数据格式以使其更简单。例如,如果您在文件的行上只有abc.com abc,那么您的字符串最终为'abc.com abc',那么您可以只.split();这假设您不需要在两个项目中的任何一个内表示空格。如果需要,您可以在另一个角色(如您的情况下为逗号)上拆分(.split(','))。如果您需要通用锤子,您可能需要研究JSON。还有ast.literal_eval可用于将文本视为简单的Python文字表达式 - 在这种情况下,您需要文件的行也包括括号括号。

答案 1 :(得分:1)

如果您愿意放弃文件中的引号并将其重写为

abc.com, abc
def.com, def
hji.com, hji

使用文件是可迭代的事实

,可以将要加载的代码减少到一行
with open('servers.list') as f:
    servers = [tuple(line.split(', ')) for line in f]

请记住,使用文件作为迭代器已经剥离了换行符。

您可以通过执行类似

的操作来允许任意空格
servers = [tuple(word.strip() for word in line.split(',')) for line in f]

使用正则表达式来解析原始格式可能更容易。您可以使用一个表达式来捕获您关注和匹配的行的各个部分,但丢弃其余部分:

import re
pattern = re.compile('\'(.+)\',\\s*\'(.+)\'')

然后,您可以从匹配的组中提取名称

with open('servers.list') as f:
    servers = [pattern.fullmatch(line).groups() for line in f]

这只是一个微不足道的例子。您可以根据实际文件格式使其变得复杂。

答案 2 :(得分:0)

试试这个:

serverlist = []

with open('/server.list', 'r') as f:
    for line in f:
        serverlist.append(tuple(line.rstrip('\n').split(',')))

<强>解释

  • 您需要一个明确的for循环,以便按预期循环每一行。
  • 每行需要list.append才能附加到您的列表中。
  • 您需要使用split(',')才能用逗号分隔。
  • 转换为tuple,因为这是您想要的输出。

列表理解方法

for循环可以压缩如下:

with open('/server.list', 'r') as f:
    serverlist = [tuple(line.rstrip('\n').split(',')) for line in f]