如何从列表理解而不是嵌套列表中获得平坦的结果?
我有一个列表 A
和一个函数 f
,它接受 A
的一项并返回一个列表。 我可以使用列表理解来转换 A
中的所有内容,例如 [f(a) for a in A]
,但这会返回一个列表列表。 假设我的输入是 [a1,a2,a3]
,结果是 [[b11,b12],[b21,b22],[b31,b32]]
。
我怎样才能得到扁平列表[b11,b12,b21,b22,b31,b32]
? 换句话说,在 Python 中,我如何获得函数式编程语言中传统上称为 flatmap
或 .NET 中的 SelectMany
的内容?
(在实际代码中,A
是目录列表,f
是os.listdir
。我想构建一个子目录的平面列表.)
另请参阅:如何从列表列表中制作平面列表?,了解更普遍的问题创建列表后将其展平。
I have a list A
, and a function f
which takes an item of A
and returns a list. I can use a list comprehension to convert everything in A
like [f(a) for a in A]
, but this returns a list of lists. Suppose my input is [a1,a2,a3]
, resulting in [[b11,b12],[b21,b22],[b31,b32]]
.
How can I get the flattened list [b11,b12,b21,b22,b31,b32]
instead? In other words, in Python, how can I get what is traditionally called flatmap
in functional programming languages, or SelectMany
in .NET?
(In the actual code, A
is a list of directories, and f
is os.listdir
. I want to build a flat list of subdirectories.)
See also: How do I make a flat list out of a list of lists? for the more general problem of flattening a list of lists after it's been created.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(18)
您可以在单个列表理解中进行嵌套迭代:
这相当于(至少在功能上):
You can have nested iterations in a single list comprehension:
which is equivalent (at least functionally) to:
itertools
解决方案效率更高,但这感觉非常Pythonic。The
itertools
solution is more efficient, but this feels very pythonic.您可以在
itertools
食谱中找到一个很好的答案:You can find a good answer in the
itertools
recipes:提出的问题是
flatmap
。 提出了一些实现,但它们可能不需要创建中间列表。 这是一种基于迭代器的实现。在 Python 2.x 中,使用
itertools.map
代替map
。The question proposed
flatmap
. Some implementations are proposed but they may unnecessary creating intermediate lists. Here is one implementation that's based on iterators.In Python 2.x, use
itertools.map
in place ofmap
.你可以直接做:
You could just do the straightforward:
您可以使用普通的加法运算符连接列表:
内置函数
sum
会将数字按顺序相加,并且可以选择从特定值开始:将以上内容组合起来以展平列表列表:
您现在可以定义您的
平面图
:编辑:我刚刚在另一个答案,我想Python将使用此解决方案不必要地构建和垃圾收集大量较小的列表是正确的。 因此,关于它最好的一点是,如果您习惯于函数式编程,那么它非常简单和简洁:-)
You can concatenate lists using the normal addition operator:
The built-in function
sum
will add the numbers in a sequence and can optionally start from a specific value:Combine the above to flatten a list of lists:
You can now define your
flatmap
:Edit: I just saw the critique in the comments for another answer and I guess it is correct that Python will needlessly build and garbage collect lots of smaller lists with this solution. So the best thing that can be said about it is that it is very simple and concise if you're used to functional programming :-)
(但蚂蚁的答案更好;为他+1)
(but Ants's answer is better; +1 for him)
itertools 将在 python2.3 及更高版本上运行
itertools will work from python2.3 and greater
您可以尝试
itertools.chain()
,如下所示:itertools.chain()
返回一个迭代器,因此传递给list()
。You could try
itertools.chain()
, like this:itertools.chain()
returns an iterator, hence the passing tolist()
.这是最简单的方法:
“a+b”指的是两个列表的串联
This is the most simple way to do it:
The 'a+b' refers to concatenation of two lists
您可以使用 pyxtension:
You can use pyxtension:
谷歌给我带来了下一个解决方案:
Google brought me next solution:
我在寻找
flatmap
并首先发现了这个问题。flatmap
基本上是原始问题要求的概括。 如果您正在寻找一种为可求和集合(例如列表)定义flatmap
的简洁方法,您可以使用它,它只比直接编写长一点
,但一开始可能不太清晰。
最明智的解决方案是将 Flatmap 作为编程语言中的基本函数,但只要它不是,您仍然可以使用更好或更具体的名称来定义它:
不幸的是,字符串不可求和,这对他们不起作用。
你可以做
但你不能做
对于字符串,你需要使用
它显然是一团糟,需要不同的函数名称,甚至不同类型的语法。 希望 Python 的类型系统将来能够得到改进。
I was looking for
flatmap
and found this question first.flatmap
is basically a generalization of what the original question asks for. If you are looking for a concise way of definingflatmap
for summable collections such as lists you can useIt's only a little longer than just writing
but also potentially less clear at first.
The sanest solution would be to have
flatmap
as a basic function inside the programming language but as long as it is not, you can still define it using a better or more concrete name:Strings are not summable unfortunately, it won't work for them.
You can do
but you can't do
For strings, you need to use
It's obviously a mess, requiring different function names and even syntax for different types. Hopefully, Python's type system will be improved in the future.
您还可以使用
numpy
来使用flatten
函数:numpy 文档
展平
You can also use the
flatten
function usingnumpy
:numpy documentation
flatten
为什么
flatten
和flat_map
函数不适用于任何使用生成器的可迭代对象?用法非常简单:
作为一个有趣的琐事,您也可以以递归方式编写
展平
。 留给有兴趣的读者分析吧!Why not
flatten
andflat_map
functions appliable to any iterable using generators?Usage is very simple:
As an interesting trivia, you can write
flatten
in a recursive manner aswell. Analysis left to the interested reader!递归可以有效地展平任何嵌套列表结构。 下面是示例代码片段:
在此代码中,
flatten_list
函数递归遍历嵌套列表,将非列表元素附加到flat_data
列表。 当遇到嵌套列表时,它会递归地调用自身,直到所有元素都被展平。 此方法可确保有效处理列表中的任何级别的嵌套,从而生成单个展平列表作为输出。Recursion can effectively flatten any nested list structure. Below is an example code snippet:
In this code, the
flatten_list
function recursively traverses the nested list, appending non-list elements to theflat_data
list. When encountering nested lists, it calls itself recursively until all elements are flattened. This approach ensures that any level of nesting within the list is handled effectively, resulting in a single flattened list as the output.递归可以有效地展平任何嵌套列表结构。 下面是示例代码片段:
在此代码中,
flatten_list
函数递归遍历嵌套列表,将非列表元素附加到flat_data
列表。 当遇到嵌套列表时,它会递归地调用自身,直到所有元素都被展平。Recursion can effectively flatten any nested list structure. Below is an example code snippet:
In this code, the
flatten_list
function recursively traverses the nested list, appending non-list elements to theflat_data
list. When encountering nested lists, it calls itself recursively until all elements are flattened.这样就可以了。
This will do.