2017-09-22 71 views
2

我的元組下面的列表:克隆元組列表中的每個元組的長度在列表

indices = [(1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)] 

我運行以下命令,獲取:

indices2 = [] 
for j in range(len(indices)): 
    indices2.append(indices[j] * len(indices[j])) 
indices2 

其中給出:

[(1,), (2,), (3,), (1, 2, 1, 2), (1, 3, 1, 3), (2, 3, 2, 3), (1, 2, 3, 1, 2, 3, 1, 2, 3)] 

不過,我想獲得:

[(1,), (2,), (3,), (1, 2), (1, 2), (1, 3), (1, 3), (2, 3), (2, 3), (1, 2, 3), (1, 2, 3), 
(1, 2, 3)] 

我在哪裏做錯了?

回答

1

您可以先創建嵌套列表的列表,然後在for循環壓平:

import itertools 

indices = [(1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)] 

indices2 = [] 
for j in range(len(indices)): 
    indices2.append([indices[j]]*len(indices[j])) 

chain = itertools.chain(*indices2) 
indices2 = list(chain) 
print indices2 

[indices[j]]*len(indices[j])創建每個列表與len(indices[j])indices[j]元組。然後使用itertools.chain將生成的嵌套列表indices2平鋪成單個非嵌套列表。

另一種方法是嵌套循環for

indices2 = [] 
for j in range(len(indices)): 
    for jln in range(len(indices[j])): 
     indices2.append(indices[j]) 

在此,循環就追加元組len(indices[j])時間。

第一個可能更pythonic,它看起來更好,第二個更簡單。如果問題需要性能升級,第一個可能還會有更多的開銷,應該進行驗證。

+1

'list(chain(* [(t,)* len(t)for t in indices]))'in one line。 – salparadise

+0

@salparadise謝謝你,我喜歡最好的一行解決方案:)如果你不想發佈答案,我會添加一個確認。 – atru

+0

試圖將所有內容都納入到首字間內可能有害,我建議你先將它改正,如果可以更具表現力,那麼就讓它成爲次要目標。此外,我把邏輯你的答案:),如果你想upvote另一個我的答案,你喜歡:) – salparadise

0

試試這個

indices = [(1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)] 
indices2=[] 
for j in indices: 
    indices2.append([j]*len(j)) 
print indices2 

與我們的代碼的問題是,當被重複的產品清單。該列表不會被克隆:所有元素都會引用同一個列表! 例如:

>>> a=[5,2,7] 
>>> a*3 
[5, 2, 7, 5, 2, 7, 5, 2, 7] 
>>> [a]*3 
[[5, 2, 7], [5, 2, 7], [5, 2, 7]] 
0

你幾乎沒有,你只需要使用extend如果要追加多個項目,並乘以它之前包裝在一些容器:

>>> indices2 = [] 
>>> for j in range(len(indices)): 
...  indices2.extend([indices[j]] * len(indices[j])) 
>>> indices2 
[(1,), (2,), (3,), (1, 2), (1, 2), (1, 3), (1, 3), (2, 3), (2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)] 

但是你甚至可以縮短它通過使用一個理解:

>>> [item for item in indices for _ in range(len(item))] 
[(1,), (2,), (3,), (1, 2), (1, 2), (1, 3), (1, 3), (2, 3), (2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)] 

至於爲什麼你的方法沒有奏效,當你乘創建tuple包含原始的重複一個新的記錄:

>>> (1, 2) * 2 
(1, 2, 1, 2) 

這不是你想要的,但是如果你把它包裝在一個list,然後乘以它,你的元組多次重複不同的元組:

>>> [(1, 2)] * 2 
[(1, 2), (1, 2)] 

並通過使用extend而不是append您只需插入「列表」的元素,所以它應該按預期工作。

然而,乘法並不真正複製,它只是多次插入相同的參考。你是在安全方面,通過使用一個修真重複一遍:

>>> [(1, 2) for _ in range(2)] 
[(1, 2), (1, 2)] 

嵌套的理解是一個比較複雜一點,但它只是取代了外循環和內extend隱式循環與內涵。它基本上相當於:

indices2 = [] 
for item in indices: 
    for _ in range(len(item)): # equivalent to the implicit loop of "extend" 
     indices2.append(item)