2017-01-26 34 views
-2

我有一個像元素的列表清單:Python的 - 優雅的方式來轉換列表的所有組合

x = ['A, B', '2', '3', 'Jan, Feb'] 
# ^    ^
# comma separated single string 

我想這個名單變成名單的每個單元的所有組合一列表這是逗號分隔的,這樣它看起來像:

[['A', '2', '3', 'Jan'], ['A', '2', '3', 'Feb'] 
['B', '2', '3', 'Jan'], ['B', '2', '3', 'Feb']] 

什麼是優雅的方式來實現這一目標使用Python的內置函數/庫?

+2

到目前爲止您做過任何嘗試了嗎? – wim

+1

鮑勃,你做了很好的描述你想要做什麼。但[SO]不是基於描述,而是基於問題和答案。你有特定的問題要問嗎? –

+0

一些字符串拆分和itertools.permutations? – doctorlove

回答

5

您可以先分割清單的基礎上逗號,的元素,然後用itertools.product以獲得所需的名單爲:

from itertools import product 
x = ['A, B', '2', '3', 'Jan, Feb'] 

new_list = list(product(*[i.split(', ') for i in x])) 

其中new_list內容將是:

[('A', '2', '3', 'Jan'), 
('A', '2', '3', 'Feb'), 
('B', '2', '3', 'Jan'), 
('B', '2', '3', 'Feb')] 

根據Dan D的評論,以下是timeit比較中間列表V/s中間生成器比較在Python 2.中級列表表達式稍快:

mquadri$ python -m timeit "from itertools import product; list(product(*(i.split(', ') for i in ['A, B', '2', '3', 'Jan, Feb'])))" 
100000 loops, best of 3: 4.83 usec per loop 

mquadri$ python -m timeit "from itertools import product; list(product(*[i.split(', ') for i in ['A, B', '2', '3', 'Jan, Feb']]))" 
100000 loops, best of 3: 3.78 usec per loop 
+0

您可以通過將生成器表達式傳遞給splat:'list(product(*(i.split(',')for i in x)))'來避免生成一個無用的列表。 –

+0

@DanD。在這種情況下,中級名單會相對更快。原因是生成器表達式在這裏是無用的,因爲爲了與* product *一起使用,必須對它進行全面評估 –

+0

編輯回答與'timeit'比較 –