嵌套 Python 列表推导式以构建列表列表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1982134/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 23:28:55  来源:igfitidea点击:

nesting python list comprehensions to construct a list of lists

pythonlist-comprehension

提问by shsteimer

I'm a python newb and am having trouble groking nested list comprehensions. I'm trying to write some code to read in a file and construct a list for each character for each line.

我是一个 python 新手,在理解嵌套列表理解时遇到了麻烦。我正在尝试编写一些代码来读取文件并为每一行的每个字符构建一个列表。

so if the file contains

所以如果文件包含

xxxcd
cdcdjkhjasld
asdasdxasda

The resulting list would be:

结果列表将是:

[
['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','a']
]

[
['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','a']
]

I have written the following code, and it works, but I have a nagging feeling that I should be able to write a nested list comprehension to do this in fewer lines of code. any suggestions would be appreciated.

我已经编写了以下代码,它可以工作,但我有一种唠叨的感觉,我应该能够编写一个嵌套列表理解来用更少的代码行来做到这一点。任何建议,将不胜感激。

data = []
f = open(file,'r')
for line in f:
    line = line.strip().upper()
    list = []
    for c in line:
        list.append(c)
    data.append(list)

回答by Edan Maor

This should help (you'll probably have to play around with it to strip the newlines or format it however you want, but the basic idea should work):

这应该会有所帮助(您可能需要使用它来删除换行符或根据需要对其进行格式化,但基本思想应该可行):

f = open(r"temp.txt")
[[c for c in line] for line in f]

回答by E.M.

In your case, you can use the listconstructor to handle the inner loop and use list comprehension for the outer loop. Something like:

在您的情况下,您可以使用list构造函数来处理内部循环并使用列表理解来处理外部循环。就像是:

f = open(file)
data = [list(line.strip().upper()) for line in f]

Given a string as input, the list constructor will create a list where each character of the string is a single element in the list.

给定一个字符串作为输入,列表构造函数将创建一个列表,其中字符串的每个字符都是列表中的一个元素。

The list comprehension is functionally equivalent to:

列表推导在功能上等同于:

data = []
for line in f:
    data.append(list(line.strip().upper()))

回答by steveha

Here is one level of list comprehension.

这是列表理解的一个级别。

data = []
f = open(file,'r')

for line in f:
    data.append([ch for ch in line.strip().upper()])

But we can do the whole thing on one go:

但是我们可以一次性完成整个事情:

f = open(file, 'rt')
data = [list(line.strip().upper()) for line in f]

This is using list()to convert a string to a list of single-character strings. We could also use nested list comprehensions, and put the open()inline:

list()用于将字符串转换为单字符字符串列表。我们还可以使用嵌套列表推导式,并放置open()内联:

data = [[ch for ch in line.strip().upper()] for line in open(file, 'rt')]

At this point, though, I think the list comprehensions are detractingfrom easy readability of what is going on.

不过,在这一点上,我认为列表理解会降低正在发生的事情的易读性。

For complicated processing, such as lists inside lists, you might want to use a forloop for the outer layer and a list comprehension for the inner loop.

对于复杂的处理,例如列表中的列表,您可能希望for对外层使用循环,对内循环使用列表理解。

Also, as Chris Lutz said in a comment, in this case there really isn't a reason to explicitly split each line into character lists; you can always treat a string as a list, and you can use string methods with a string, but you can't use string methods with a list. (Well, you could use ''.join()to rejoin the list back to a string, but why not just leave it as a string?)

此外,正如 Chris Lutz 在评论中所说,在这种情况下,确实没有理由将每一行明确拆分为字符列表;您始终可以将字符串视为列表,并且可以对字符串使用字符串方法,但不能对列表使用字符串方法。(好吧,您可以使用''.join()将列表重新加入为字符串,但为什么不将其保留为字符串呢?)

回答by Robert Rossney

The only really significant difference between strings and lists of characters is that strings are immutable. You can iterate over and slice strings just as you would lists. And it's much more convenient to handle strings as strings, since they support string methods and lists don't.

字符串和字符列表之间唯一真正重要的区别是字符串是不可变的。您可以像列表一样迭代和切片字符串。将字符串作为字符串处理要方便得多,因为它们支持字符串方法而列表不支持。

So for most applications, I wouldn't bother converting the items in datato a list; I'd just do:

因此,对于大多数应用程序,我不会费心将项目转换data为列表;我只会做:

data = [line.strip() for line in open(filename, 'r')]

When I needed to manipulate strings in dataas mutable lists, I'd use listto convert them, and jointo put them back, e.g.:

当我需要将字符串data作为可变列表进行操作时,我会list用来转换它们,然后将它们join放回去,例如:

data[2] = ''.join(sorted(list(data[2])))

Of course, if all you're going to do with these strings is modify them, then go ahead, store them as lists.

当然,如果您对这些字符串所做的只是修改它们,那么继续,将它们存储为列表。

回答by interjay

data = [list(line.strip().upper()) for line in open(file,'r')]

回答by Skurmedel

First off you could combine the line.strip().upper() part with your outer for-loop, like this:

首先,您可以将 line.strip().upper() 部分与外部 for 循环结合起来,如下所示:

for line in [l.strip().upper() for l in f]:
    # do stuff

Then you could make the iteration over the characters into a list comprehension, but it wouldn't be shorter or clearer. The neatest way to do what you do there is this:

然后您可以将字符上的迭代变成列表理解,但它不会更短或更清晰。做你在那里做的最简洁的方法是这样的:

list(someString)

Thus you could do:

因此你可以这样做:

data = [list(l.strip().upper()) for l in f]

I don't know if it states your intentions that well though. Error handling is also an issue, the whole expression will die if there is a problem on the way.

我不知道它是否能很好地表达你的意图。错误处理也是一个问题,如果途中出现问题,整个表达式就会死亡。



If you don't need to store the whole file and all the lines in memory, you could make it into a generator expression. This is very useful when processing huge files and you only need to process a chunk at a time. Generator expressions use parentheses instead, like so:

如果您不需要将整个文件和所有行存储在内存中,您可以将其放入生成器表达式中。这在处理大文件时非常有用,您一次只需要处理一个块。生成器表达式使用括​​号代替,如下所示:

data = (list(l.strip().upper()) for l in f)

datawill become a generator which runs the expression for each line in the file, but only when you iterate over it; compare that to a list comprehension which will create a huge list in memory. Note that datais not a list, but a generator, and more a kin to a iterator in C++ or IEnumerator in C#.

data将成为一个生成器,为文件中的每一行运行表达式,但仅当您对其进行迭代时;将其与列表理解进行比较,列表理解将在内存中创建一个巨大的列表。请注意,这data不是列表,而是生成器,更像是 C++ 中的迭代器或 C# 中的 IEnumerator。

A generator can be fed into a list easily: list(someGenerator)That would defeat the purpose somewhat but is sometimes a necessity.

一个生成器可以很容易地输入到一个列表中:list(someGenerator)这会在某种程度上违背目的,但有时是必要的。

回答by jbochi

>>> 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']]