如果您只是继承或下载了这些文件并且无法对格式做任何事情,并且您知道它们应该被视为 Pythonlist
的行,ast.literal_eval
那么这是最好的答案,正如 steveha 解释的那样:
t = open('filename.txt', 'r')
alist = []
for i in contents:
alist.append(ast.literal_eval(i))
如果您继承或下载了这些文件,并且只是猜测格式,那么它们实际上可能打算被读取为 JSON 行,因为它们绝对是有效的 JSON,就像它们是有效的 Python 文字一样。在这种情况下:
t = open('filename.txt', 'r')
alist = []
for i in contents:
alist.append(json.loads(i))
但是,如果您是首先创建这些文件的人,那么您应该以专为序列化设计的方式创建它们。
例如,而不是这个:
t = open('filename.txt', 'w')
for i in alist:
print >>t, i
做这样的事情:
t = open('filename.txt', 'w')
json.dump(alist, t)
然后你可以这样写你的阅读代码:
t = open('filename.txt', 'r')
alist = json.load(t)
JSON、YAML 或 Pickle 等序列化格式的全部意义在于,它们是专门设计的,以便您可以写入一个值,然后再读回相同的值。
print
,str
等函数不是为此而设计的;它们的设计使您可以以最好的人类可读形式显示一个值,即使以后很难或不可能读回。
该功能repr
介于两者之间。它的设计目的是让玩交互式提示的人可读,因此如果可能的话,它会为您提供一个字符串,您可以在提示中键入该字符串以获取相同的值。这意味着,在某些情况下,ast.literal_eval
是 的倒数repr
,就像json.load
的倒数一样json.dump
。但是你不应该依赖这个,即使在处理它工作的类型时也是如此。
关于您的代码的一些附注:
t = open('filename.txt', 'r+w')
如果您只是要读取文件,请不要尝试打开它进行写入。此外,如果您确实想同时打开读取和写入,则正确的模式字符串是r+
,而不是r+w
。(你这样做的方式在技术上是一个错误,但大多数 Python 版本都会忽略w
,所以你可以侥幸逃脱。)
如果模式是r
,则根本不需要指定它,因为这是默认设置。
同时,你永远不会close
文件。最简单的方法是使用with
语句。
contents = t.readlines()
几乎从来没有一个很好的理由打电话readlines()
。这为您提供了一系列行 - 但文件本身已经是一系列行。你所做的只是制作一个额外的副本。
alist = []
for i in contents:
alist.append(i)
这种模式——创建一个空列表,然后在循环中附加到它——是如此普遍,以至于 Python 有一个快捷方式,称为列表推导。与显式循环相比,理解更简洁、更易读、更难出错、速度更快,因此大部分时间都值得使用它们。
最后,最好给变量起有意义的名称。特别是如果您希望其他人(或您自己,六个月后)能够调试您的代码。如果它工作得很好,我们可以通过它们的作用来判断变量的含义——但如果不是,我们就无法修复它,除非我们能猜出它们应该是什么意思,而名称是表明这一点的最佳方式。
所以,把它们放在一起,你的原始代码可以写成:
with open('filename.txt') as textfile:
alist = [line for line in textfile]
各种固定版本是:
with open('filename.txt') as textfile:
alist = [ast.literal_eval(line) for line in textfile]
with open('filename.txt') as textfile:
alist = [json.loads(line) for line in textfile]
with open('filename.txt') as textfile:
alist = json.load(textfile)