嵌套Python列表解析构建列表的列表
我是一个python newb,并且遇到了嵌套列表解析的困难。我试图编写一些代码来读取文件,并为每一行的每个字符构造一个列表。嵌套Python列表解析构建列表的列表
所以如果该文件包含
xxxcd
cdcdjkhjasld
asdasdxasda
结果列表将是:
[
[ 'X', 'X', 'X', 'C', 'd'] 'd','c','d','j','k','h','j','a','s','1','d' ]
['a','s','d','a','s','d','x','a','s','d','a']
]
我写了下面的代码,它的工作原理,但我有一个唠叨的感觉,我应该能够编写一个嵌套的列表理解,以更少的代码行来做到这一点。任何建议,将不胜感激。
data = []
f = open(file,'r')
for line in f:
line = line.strip().upper()
list = []
for c in line:
list.append(c)
data.append(list)
这应该有所帮助(你可能需要玩弄它去剥离换行符或格式你想要的东西,但基本的思路应该工作):
f = open(r"temp.txt")
[[c for c in line] for line in f]
任何人都可以解释这种形式的内在理解是如何工作的吗?我一直在为此而苦苦挣扎。 – 2016-01-20 18:44:24
data = [list(line.strip().upper()) for line in open(file,'r')]
+1,但我宁愿将每个条目作为字符串保留在列表中。由于字符串可以被编入索引,因此您仍然可以将它视为二维字符数组。仅当OP计划对行进行更改时,才需要“list(...)”部分。 – 2009-12-30 20:07:29
这里是列表理解的一个水平。
data = []
f = open(file,'r')
for line in f:
data.append([ch for ch in line.strip().upper()])
但我们可以做一气呵成,整个事情:
f = open(file, 'rt')
data = [list(line.strip().upper()) for line in f]
这是使用list()
将字符串转换为单字符字符串列表。我们也可以使用嵌套列表内涵,并把open()
在线:
data = [[ch for ch in line.strip().upper()] for line in open(file, 'rt')]
在这一点上,不过,我觉得列表内涵是从正在发生的事情的容易可读性减损。
对于复杂的处理,例如列表中的列表,您可能需要使用外层的for
循环和内循环的列表理解。另外,正如Chris Lutz在评论中所说,在这种情况下,确实没有理由将每一行明确地分割为字符列表;您始终可以将字符串视为列表,并且可以将字符串方法与字符串一起使用,但不能将字符串方法与列表一起使用。 (嗯,你可以使用''.join()
重新加入列表回到一个字符串,但为什么不把它作为一个字符串?)
首先,你可以结合line.strip()与外的环上()的一部分,这样的:
for line in [l.strip().upper() for l in f]:
# do stuff
然后,你可以将字符迭代到列表c中不理解,但它不会更短或更清晰。最巧妙的方法做,你在那里做什么是这样的:
list(someString)
因此你可以这样做:
data = [list(l.strip().upper()) for l in f]
我不知道,如果它规定你的意图很好,虽然这一点。错误处理也是一个问题,如果出现问题,整个表达式将会消失。
如果您不需要将整个文件和所有行存储在内存中,则可以将其设置为生成器表达式。这在处理大文件时非常有用,并且您只需要一次处理大块文件。生成器表达式用括号代替,就像这样:
data = (list(l.strip().upper()) for l in f)
data
将成为它运行在文件中的每一行表达的发电机,但只有当你迭代它;将它与列表理解相比较,这将在内存中创建一个巨大的列表。请注意,data
不是一个列表,而是一个生成器,更多的是C++中的迭代器或C#中的IEnumerator的一个亲属。
一个发电机可以很容易地进入一个列表:list(someGenerator)
这会有点失败的目的,但有时是必要的。
>>> f = file('teste.txt')
>>> print map(lambda x: [c for c in x][:-1], f)
[['x', 'x', 'x', 'c', 'd'], ['c', 'd', 'c', 'd', 'j', 'k', 'h', 'j', 'a', 's', 'l', 'd'], ['a', 's', 'd', 'a', 's', 'd', 'x', 'a', 's', 'd']]
在你的情况,你可以使用list
构造函数来处理内部循环,并使用列表理解为外环。喜欢的东西:
f = open(file)
data = [list(line.strip().upper()) for line in f]
给定一个字符串作为输入,列表构造将创建一个列表,其中字符串中的每个字符是列表中的一个元素。
列表内涵在功能上等同于:字符的字符串和列表之间
data = []
for line in f:
data.append(list(line.strip().upper()))
唯一真正显著的区别是,字符串是不可变的。您可以按照列出的方式遍历和切分字符串。将字符串作为字符串处理会更方便,因为它们支持字符串方法,而列表不支持字符串方法。
因此,对于大多数应用程序,我不会打扰将data
中的项目转换为列表;我只是做:
data = [line.strip() for line in open(filename, 'r')]
当我需要操作字符串在data
为可变的名单,我会使用list
将它们转换,并join
把他们回来,例如:
data[2] = ''.join(sorted(list(data[2])))
当然,如果你要对这些字符串进行修改,请继续,将它们存储为列表。
对于简单性和可读性有很多要说的。虽然你可能能够通过嵌套理解获得相同的效果,但也可能最终导致无意模糊处理。 – 2009-12-30 20:03:58
另外,不要有一个名为'file'的变量。我知道'file'和'open'是同义词,但是如果你需要测试'isinstance(f,file)',你会后悔的。也许称它为'filename'?名字为'list'的变量也是如此。 – 2009-12-30 20:10:04