Python 嵌套列表上的列表理解?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18072759/
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
List comprehension on a nested list?
提问by Boy Pasmo
I have this nested list:
我有这个嵌套列表:
l = [['40', '20', '10', '30'], ['20', '20', '20', '20', '20', '30', '20'], ['30', '20', '30', '50', '10', '30', '20', '20', '20'], ['100', '100'], ['100', '100', '100', '100', '100'], ['100', '100', '100', '100']]
Now, what I want to do is convert each element in a list to float. My solution is this:
现在,我想要做的是将列表中的每个元素转换为浮动。我的解决方案是这样的:
newList = []
for x in l:
for y in x:
newList.append(float(y))
But can this be done using nested list comprehension, right?
但这可以使用嵌套列表理解来完成,对吗?
what I've done is:
我所做的是:
[float(y) for y in x for x in l]
But then the result is bunch of 100's with the sum of 2400.
但结果是一堆 100,总和为 2400。
any solution, an explanation would be much appreciated. Thanks!
任何解决方案,一个解释将不胜感激。谢谢!
采纳答案by Andrew Clark
Here is how you would do this with a nested list comprehension:
以下是使用嵌套列表推导式执行此操作的方法:
[[float(y) for y in x] for x in l]
This would give you a list of lists, similar to what you started with except with floats instead of strings. If you want one flat list then you would use [float(y) for x in l for y in x]
.
这将为您提供一个列表列表,类似于您开始使用的列表,除了使用浮点数而不是字符串。如果你想要一个平面列表,那么你可以使用[float(y) for x in l for y in x]
.
回答by falsetru
>>> l = [['40', '20', '10', '30'], ['20', '20', '20', '20', '20', '30', '20'], ['30', '20', '30', '50', '10', '30', '20', '20', '20'], ['100', '100'], ['100', '100', '100', '100', '100'], ['100', '100', '100', '100']]
>>> new_list = [float(x) for xs in l for x in xs]
>>> new_list
[40.0, 20.0, 10.0, 30.0, 20.0, 20.0, 20.0, 20.0, 20.0, 30.0, 20.0, 30.0, 20.0, 30.0, 50.0, 10.0, 30.0, 20.0, 20.0, 20.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0]
回答by Victor
Yes, you can do it with such a code:
是的,你可以用这样的代码做到这一点:
l = [[float(y) for y in x] for x in l]
回答by narayan
If you don't like nested list comprehensions, you can make use of the mapfunction as well,
如果您不喜欢嵌套列表推导式,也可以使用map函数,
>>> from pprint import pprint
>>> l = l = [['40', '20', '10', '30'], ['20', '20', '20', '20', '20', '30', '20'], ['30', '20', '30', '50', '10', '30', '20', '20', '20'], ['100', '100'], ['100', '100', '100', '100', '100'], ['100', '100', '100', '100']]
>>> pprint(l)
[['40', '20', '10', '30'],
['20', '20', '20', '20', '20', '30', '20'],
['30', '20', '30', '50', '10', '30', '20', '20', '20'],
['100', '100'],
['100', '100', '100', '100', '100'],
['100', '100', '100', '100']]
>>> float_l = [map(float, nested_list) for nested_list in l]
>>> pprint(float_l)
[[40.0, 20.0, 10.0, 30.0],
[20.0, 20.0, 20.0, 20.0, 20.0, 30.0, 20.0],
[30.0, 20.0, 30.0, 50.0, 10.0, 30.0, 20.0, 20.0, 20.0],
[100.0, 100.0],
[100.0, 100.0, 100.0, 100.0, 100.0],
[100.0, 100.0, 100.0, 100.0]]
回答by Thomasillo
The best way to do this in my opinion is to use python's itertools
package.
在我看来,最好的方法是使用 python 的itertools
包。
>>>import itertools
>>>l1 = [1,2,3]
>>>l2 = [10,20,30]
>>>[l*2 for l in itertools.chain(*[l1,l2])]
[2, 4, 6, 20, 40, 60]
回答by Harry Binswanger
Not sure what your desired output is, but if you're using list comprehension, the order follows the order of nested loops, which you have backwards. So I got the what I think you want with:
不确定您想要的输出是什么,但如果您使用列表理解,则顺序遵循嵌套循环的顺序,而嵌套循环的顺序是向后的。所以我得到了我认为你想要的:
[float(y) for x in l for y in x]
The principle is: use the same order you'd use in writing it out as nested for loops.
原则是:使用与嵌套 for 循环相同的顺序写出它。
回答by Aakash Goel
This Problem can be solved without using for loop.Single line code will be sufficient for this. Using Nested Map with lambda function will also works here.
这个问题可以不用for循环来解决。单行代码就足够了。使用带有 lambda 函数的嵌套映射也适用于此。
l = [['40', '20', '10', '30'], ['20', '20', '20', '20', '20', '30', '20'], ['30', '20', '30', '50', '10', '30', '20', '20', '20'], ['100', '100'], ['100', '100', '100', '100', '100'], ['100', '100', '100', '100']]
map(lambda x:map(lambda y:float(y),x),l)
And Output List would be as follows:
输出列表如下:
[[40.0, 20.0, 10.0, 30.0], [20.0, 20.0, 20.0, 20.0, 20.0, 30.0, 20.0], [30.0, 20.0, 30.0, 50.0, 10.0, 30.0, 20.0, 20.0, 20.0], [100.0, 100.0], [100.0, 100.0, 100.0, 100.0, 100.0], [100.0, 100.0, 100.0, 100.0]]
回答by Rahul
Here is how to convert nested for loop to nested list comprehension:
以下是如何将嵌套 for 循环转换为嵌套列表推导式:
Here is how nested list comprehension works:
以下是嵌套列表理解的工作原理:
l a b c d e f
↓ ↓ ↓ ↓ ↓ ↓ ↓
In [1]: l = [ [ [ [ [ [ 1 ] ] ] ] ] ]
In [2]: for a in l:
...: for b in a:
...: for c in b:
...: for d in c:
...: for e in d:
...: for f in e:
...: print(float(f))
...:
1.0
In [3]: [float(f)
for a in l
...: for b in a
...: for c in b
...: for d in c
...: for e in d
...: for f in e]
Out[3]: [1.0]
For your case, it will be something like this.
对于您的情况,它将是这样的。
In [4]: new_list = [float(y) for x in l for y in x]
回答by Aaditya Ura
Since i am little late here but i wanted to share how actually list comprehension works especially nested list comprehension :
由于我在这里有点晚了,但我想分享列表理解实际上是如何工作的,尤其是嵌套列表理解:
New_list= [[float(y) for x in l]
is actually same as :
实际上是一样的:
New_list=[]
for x in l:
New_list.append(x)
And now nested list comprehension :
现在嵌套列表理解:
[[float(y) for y in x] for x in l]
is same as ;
是一样的;
new_list=[]
for x in l:
sub_list=[]
for y in x:
sub_list.append(float(y))
new_list.append(sub_list)
print(new_list)
output:
输出:
[[40.0, 20.0, 10.0, 30.0], [20.0, 20.0, 20.0, 20.0, 20.0, 30.0, 20.0], [30.0, 20.0, 30.0, 50.0, 10.0, 30.0, 20.0, 20.0, 20.0], [100.0, 100.0], [100.0, 100.0, 100.0, 100.0, 100.0], [100.0, 100.0, 100.0, 100.0]]
回答by Sohaib Farooqi
I had a similar problem to solve so I came across this question. I did a performance comparison of Andrew Clark's and narayan's answer which I would like to share.
我有一个类似的问题要解决,所以我遇到了这个问题。我对 Andrew Clark 和 narayan 的回答进行了性能比较,我想分享一下。
The primary difference between two answers is how they iterate over inner lists. One of them uses builtin map, while other is using list comprehension. Map function has slight performance advantage to its equivalent list comprehension if it doesn't require the use lambdas. So in context of this question map
should perform slightly better than list comprehension.
两个答案之间的主要区别在于它们如何迭代内部列表。其中一个使用内置map,而另一个使用列表理解。如果 Map 函数不需要使用 lambdas ,它对其等效的列表理解具有轻微的性能优势。所以在这个问题的上下文中map
应该比列表理解略好。
Lets do a performance benchmark to see if it is actually true. I used python version 3.5.0 to perform all these tests. In first set of tests I would like to keep elements per list to be 10and vary number of lists from 10-100,000
让我们做一个性能基准测试,看看它是否真的是真的。我使用 python 版本 3.5.0 来执行所有这些测试。在第一组测试中,我希望将每个列表的元素保持为10,并将列表数量从10-100,000 不等
>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,10))]*10]"
>>> 100000 loops, best of 3: 15.2 usec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,10))]*10]"
>>> 10000 loops, best of 3: 19.6 usec per loop
>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,10))]*100]"
>>> 100000 loops, best of 3: 15.2 usec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,10))]*100]"
>>> 10000 loops, best of 3: 19.6 usec per loop
>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,10))]*1000]"
>>> 1000 loops, best of 3: 1.43 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,10))]*1000]"
>>> 100 loops, best of 3: 1.91 msec per loop
>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,10))]*10000]"
>>> 100 loops, best of 3: 13.6 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,10))]*10000]"
>>> 10 loops, best of 3: 19.1 msec per loop
>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,10))]*100000]"
>>> 10 loops, best of 3: 164 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,10))]*100000]"
>>> 10 loops, best of 3: 216 msec per loop
In the next set of tests I would like to raise number of elements per lists to 100.
在下一组测试中,我想将每个列表的元素数提高到100。
>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,100))]*10]"
>>> 10000 loops, best of 3: 110 usec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,100))]*10]"
>>> 10000 loops, best of 3: 151 usec per loop
>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,100))]*100]"
>>> 1000 loops, best of 3: 1.11 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,100))]*100]"
>>> 1000 loops, best of 3: 1.5 msec per loop
>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,100))]*1000]"
>>> 100 loops, best of 3: 11.2 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,100))]*1000]"
>>> 100 loops, best of 3: 16.7 msec per loop
>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,100))]*10000]"
>>> 10 loops, best of 3: 134 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,100))]*10000]"
>>> 10 loops, best of 3: 171 msec per loop
>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,100))]*100000]"
>>> 10 loops, best of 3: 1.32 sec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,100))]*100000]"
>>> 10 loops, best of 3: 1.7 sec per loop
Lets take a brave step and modify the number of elements in lists to be 1000
让我们勇敢地将列表中的元素数量修改为1000
>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,1000))]*10]"
>>> 1000 loops, best of 3: 800 usec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,1000))]*10]"
>>> 1000 loops, best of 3: 1.16 msec per loop
>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,1000))]*100]"
>>> 100 loops, best of 3: 8.26 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,1000))]*100]"
>>> 100 loops, best of 3: 11.7 msec per loop
>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,1000))]*1000]"
>>> 10 loops, best of 3: 83.8 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,1000))]*1000]"
>>> 10 loops, best of 3: 118 msec per loop
>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,1000))]*10000]"
>>> 10 loops, best of 3: 868 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,1000))]*10000]"
>>> 10 loops, best of 3: 1.23 sec per loop
>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,1000))]*100000]"
>>> 10 loops, best of 3: 9.2 sec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,1000))]*100000]"
>>> 10 loops, best of 3: 12.7 sec per loop
From these test we can conclude that map
has a performance benefit over list comprehension in this case. This is also applicable if you are trying to cast to either int
or str
. For small number of lists with less elements per list, the difference is negligible. For larger lists with more elements per list one might like to use map
instead of list comprehension, but it totally depends on application needs.
从这些测试中我们可以得出结论,map
在这种情况下,它比列表理解具有性能优势。如果您尝试强制转换为int
或 ,这也适用str
。对于每个列表元素较少的少量列表,差异可以忽略不计。对于每个列表具有更多元素的较大列表,人们可能更喜欢使用map
列表理解,但这完全取决于应用程序的需求。
However I personally find list comprehension to be more readable and idiomatic than map
. It is a de-facto standard in python. Usually people are more proficient and comfortable(specially beginner) in using list comprehension than map
.
但是,我个人认为列表理解比map
. 它是 Python 中的事实上的标准。通常人们在使用列表理解方面比map
.