我是一个python newb,并且在查看嵌套列表推导方面遇到了麻烦。我正在尝试编写一些代码来读取文件,并为每一行的每个字符构建一个列表。
所以如果文件包含
xxxcd
cdcdjkhjasld
asdasdxasda
结果列表为:
[
[ 'X', 'X', 'X', 'C', 'd']
[ 'C', 'd', 'C', 'd', 'J', 'K', 'H', 'J', 'A', 'S', 'L', 'd'] <登记/>
[ '一个', '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)
答案 0 :(得分:18)
这应该有所帮助(你可能不得不玩它来剥离新行或按照你想要的格式化它,但基本的想法应该有效):
f = open(r"temp.txt")
[[c for c in line] for line in f]
答案 1 :(得分:3)
在您的情况下,您可以使用list
构造函数来处理内部循环并使用外部循环的列表理解。类似的东西:
f = open(file)
data = [list(line.strip().upper()) for line in f]
给定一个字符串作为输入,列表构造函数将创建一个列表,其中字符串的每个字符都是列表中的单个元素。
列表理解在功能上等同于:
data = []
for line in f:
data.append(list(line.strip().upper()))
答案 2 :(得分:2)
这是列表理解的一个层次。
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()
将列表重新加入字符串,但为什么不将其保留为字符串?)
答案 3 :(得分:1)
data = [list(line.strip().upper()) for line in open(file,'r')]
答案 4 :(得分:1)
字符串和字符列表之间唯一真正重要的区别是字符串是不可变的。您可以像列出一样迭代并切片字符串。将字符串作为字符串处理会更方便,因为它们支持字符串方法,而列表则不支持。
因此,对于大多数应用程序,我不会费心将data
中的项目转换为列表;我只是这样做:
data = [line.strip() for line in open(filename, 'r')]
当我需要将data
中的字符串作为可变列表进行操作时,我会使用list
来转换它们,并使用join
将它们放回去,例如:
data[2] = ''.join(sorted(list(data[2])))
当然,如果要对这些字符串进行修改,请修改它们,然后继续将它们存储为列表。
答案 5 :(得分:0)
首先,你可以将line.strip()。upper()部分与你的外部for循环结合起来,如下所示:
for line in [l.strip().upper() for l in f]:
# do stuff
然后你可以将字符的迭代变成列表理解,但它不会更短或更清晰。做你做的最好的方法是:
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)
这会在一定程度上破坏目的但有时是必要的。
答案 6 :(得分:0)
>>> 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']]