2013-08-06 43 views
132

我有這樣的嵌套列表:在嵌套列表上理解列表?

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

現在,我想要做的是每個元素轉換列表中的浮動。我的解決方案是這樣的:

newList = [] 
for x in l: 
    for y in x: 
    newList.append(float(y)) 

但這可以使用嵌套列表理解,對嗎?

什麼,我所做的就是:

[float(y) for y in x for x in l] 

但隨後的結果是與2400的

任何解決方案和一束100的的,的解釋將不勝感激。謝謝!

+12

你是否也想要展平你的名單? –

+0

@GregHewgill:OP沒有回覆,但根據他們接受的答案,似乎他們想保持嵌套。 – smci

回答

195

這裏是你將如何使用嵌套列表理解這樣做:

[[float(y) for y in x] for x in l] 

這會給你列出,類似的列表,你開始只是用浮漂,而不是字符串。如果你想要一個平面列表,那麼你會使用[float(y) for x in l for y in x]

36
>>> 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] 
2

是的,你可以用這樣的代碼做到這一點:

l = [[float(y) for y in x] for x in l] 
+0

'[float(y)for y in x for x in l]'這將導致一堆100個數的總和爲2400. –

3

如果你不喜歡嵌套列表理解,你可以使用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]] 
+0

您的代碼生成地圖對象而不是列表: >>> >>> float_l = [ nested_list的地圖(float,nested_list)[] [ ] [[], [], [], [], , [<在0x484b048地圖>] [<地圖在0x484b0b8>]] ' 但是添加附加的呼叫到列表它按預期工作: '>>> FLOAT_L = [表(圖(浮筒,nested_list ))for nested_list in l]' – pixelperfect

+0

@pixelperfect這是由於(* misinformed * ..)在'python3'中改變,使得生成器不能被理解。 – javadba

0

在我看來,最好的方法是使用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] 
16

不知道你想要的輸出是什麼,但如果你使用列表中理解,順序如下嵌套循環,你有向後的順序。所以,我得到了你想要我認爲:

[float(y) for x in l for y in x] 

其原理是:利用你在寫出來嵌套的for循環使用相同的順序。

+0

這應該是答案,因爲有些時候我們不希望將括號括起來iteratool – zinking

+0

這可能不是正確的答案,因爲它輸出一個非嵌套列表,但這正是我正在尋找的,特別是*原則* 。謝謝! –

1

這個問題可以在不使用循環的情況下解決。單線代碼就足夠了。使用帶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) 

並且輸出列表如下:

[[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]0]

+1

與安德魯·克拉克或哈里·賓斯旺格的解決方案(更多香草列表理解)相比,lambda表達式有什麼優勢?由於lambda似乎難以閱讀。 – Splatmistro

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

#Which can be written in single line as 
In [4]: [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[4]: [1.0] 
+0

超好用!清楚地說明循環(從上到下)從發生器左側到右側排列。這在'(f(x)for x in l)'中不明顯,因爲它將循環等效的第二行放在左邊。 – user48956

+0

嵌套理解的(非常明顯的乍一看)語法的很有用的例子。 – wom

4

既然我有點晚了這裏,但我想分享列表理解如何實際工作尤其是嵌套列表理解:

New_list= [[float(y) for x in l] 

實際上是一樣的:

New_list=[] 
for x in l: 
    New_list.append(x) 

現在嵌套列表理解:

[[float(y) for y in x] for x in l] 

與之相同;

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) 

輸出:

[[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]] 
2

我有一個類似的問題要解決,所以我遇到了這個問題。我做了一個安德魯克拉克和納拉揚的答案的性能比較,我想分享一下。

兩個答案的主要區別在於它們如何遍歷內部列表。其中一個使用內建的map,而其他使用列表理解。 Map function has slight performance advantage to its equivalent list comprehension if it doesn't require the use lambdas。所以在這個問題的背景下,map應該比列表理解執行略好。

讓我們做一個性能基準來判斷它是否真的如此。我使用python 3.5.0版來執行所有這些測試。在第一組測試,我想保持每列表元素是和改變列表的數量從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 

enter image description here

在下一組的測試中,我想將每個列表的元素數量提高到。

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

enter image description here

讓作爲勇敢步驟和修改列表元素的數量是

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

enter image description here

從這些測試中,我們可以得出結論,map在這種情況下具有比列表理解更好的性能優勢。如果您嘗試投射到intstr,這也適用。對於每個列表中少量元素的列表數量較少,差異可以忽略不計。對於每個列表中包含更多元素的較大列表,人們可能喜歡使用map而不是列表理解,但完全取決於應用程序需求。

但是我個人覺得列表理解比map更具可讀性和慣用性。這是python中事實上的標準。通常人們在使用列表理解方面比map更熟練和舒適(特別是初學者)。