我目前有一个硬编码到我的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'"]
列表无法正常工作。那我究竟做错了什么?我是否正确读取文件或我是否正确格式化文件?或其他什么?
答案 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]