Python 文件中的.readlines()列表未索引值
我有一个txt文件,其内容如下所示:Python 文件中的.readlines()列表未索引值,python,list,python-2.7,Python,List,Python 2.7,我有一个txt文件,其内容如下所示: [1,2,3,4] [5,6,7,8] t = open('filename.txt', 'w') json.dump(alist, t) t = open('filename.txt', 'r') alist = json.load(t) 我使用以下代码将这些列表放入列表中: t = open('filename.txt', 'r+w') contents = t.readlines() alist = [] for i in contents:
[1,2,3,4]
[5,6,7,8]
t = open('filename.txt', 'w')
json.dump(alist, t)
t = open('filename.txt', 'r')
alist = json.load(t)
我使用以下代码将这些列表放入列表中:
t = open('filename.txt', 'r+w')
contents = t.readlines()
alist = []
for i in contents:
alist.append(i)
当我跑的时候
alist[0]
我明白了
但是当我跑的时候
for a in alist:
print a[0]
我明白了
而不是列表中的第一个值。.readlines()
将行作为字符串读取。该字符串的第一个字符是[
如果要读取文本文件并将其“反序列化”为数据结构,最简单的方法是使用Python内置的eval()
函数。更安全的方法是使用ast.literal\u eval()
建议代码:
import ast
with open("filename.txt") as f:
alist = [ast.literal_eval(line) for line in f]
print(type(alist[0])) # prints: <type 'list'>
print(alist[0]) # prints: [1,2,3,4]
导入ast
将open(“filename.txt”)作为f:
alist=[ast.literal_eval(line)表示f中的行]
打印(类型(列表[0])#打印:
打印(列表[0])#打印:[1,2,3,4]
我们几乎不想调用.readlines()
;它会在文件的所有行中发出声音,因此如果文件非常大,它会导致程序的内存使用量增加。打开的文件句柄对象(在我的示例中,f
)可以用作迭代器,每次迭代时,它都会从文件中产生一行。因此,for
循环或列表理解将从文件中一次提取一行。因此,此示例程序不会将整个文件保存在内存中;在构建列表时,它一次只保留一行。如果此程序调用.readlines()
它将保留所有行和列表,因此峰值内存使用率将更高。(当然,对于本例中这样一个小的输入文件来说,这并不重要。但是,使用内存效率高的方法很容易做到,为什么不呢?)
使用和
一起打开文件始终是一种良好的做法。这样,当您使用完文件后,您就知道该文件将被正确关闭
我们使用列表理解来构建
ast.literal_eval()结果的列表
,对于给定的输入文件,它每行返回一个列表,因此alist
将是一个列表。您拥有的是一个字符串列表。带括号和逗号的字符串并不是一个神奇的列表,它只是一个带括号和逗号的字符串
alist
是列表。在循环中,a
是该列表中的一项:首先,它是alist[0]
,然后是alist[1]
等等。因此,a[0]
要求alist[0][0]
,alist[1][0]
,等等:每行的第一个字符。这就是你得到的
如果您想将其转换为实际的Python列表,请使用
ast.literal_eval()
如果您只是继承或下载了这些文件,并且对格式无能为力,并且您知道它们应该被视为Pythonlist
s的行,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
这样做:
[1,2,3,4]
[5,6,7,8]
t = open('filename.txt', 'w')
json.dump(alist, t)
t = open('filename.txt', 'r')
alist = json.load(t)
然后您可以这样编写阅读代码:
[1,2,3,4]
[5,6,7,8]
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\u eval
与repr
相反,就像load
与json.dump
相反。但是,即使处理工作类型,也不应该依赖于此
关于代码的一些旁注:
t = open('filename.txt', 'r+w')
如果您只想读取文件,不要试图打开它进行写入。此外,如果您确实想同时打开文件进行读取和写入,正确的模式字符串是r+
,而不是r+w
(从技术上讲,您这样做是错误的,但大多数Python版本都会忽略w
,因此您可以侥幸逃脱。)
如果模式是r
,则根本不需要指定它,因为这是默认模式
同时,您永远不会关闭文件。最简单的方法是使用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)
这个文件是如何创建的