2017-03-04 32 views
1

我有以下示例。在列表和元組之間連接/分配

prefix = ['blue ','brown '] 
suffix = [('dog','shoes','bike'), ('tree','cat','car')] 

我想獲得一個新的列表,看起來像這樣:

[('blue dog', 'blue shoes', 'blue bike'), 
('blue tree', 'blue cat', 'blue car'), 
('brown dog', 'brown shoes', 'brown bike'), 
('brown tree', 'brown cat', 'brown car')] 

就是我要分發並在每個元組連接第一列表中的每個元素與每個項目第二個列表。第二個列表可以有2個以上的元組,但是每個元組總是有3個元素。

任何方式來做到這一點,而無需編寫嵌套for循環?

回答

2

使用嵌套列表理解:

lst = [tuple(i+x for x in j) for i in prefix for j in suffix] 
print(lst) 
# [('blue dog', 'blue shoes', 'blue bike'), 
# ('blue tree', 'blue cat', 'blue car'), 
# ('brown dog', 'brown shoes', 'brown bike'), 
# ('brown tree', 'brown cat', 'brown car')] 

可以解開的理解成一個for循環更好地瞭解它是如何工作:

lst = [] 
for i in prefix: 
    for j in suffix: 
     lst.append(tuple(i+x for x in j)) 
+0

這看起來很不錯 - 我試圖直觀地理解這一點,以及如何從左到右或從右到左閱讀它。你有沒有等效的循環建設? – laszlopanaflex

+0

@laszlopanaflex更新! –

+0

謝謝 - 這是我奮鬥了一下,瞭解python如何解釋這些嵌套的語句 - 其他示例顯示從左到右,在這種情況下,我會預料會出現問題,因爲「j」尚未定義。 – laszlopanaflex

0

無法看到任何方式獲得四個獨立的tupels沒有嵌套(顯式或其他)。

itertools.product將組合列表。

>>> from itertools import product 
>>> for thing in suffix: 
    print(list(map(''.join, product(prefix, thing)))) 


['blue dog', 'blue shoes', 'blue bike', 'brown dog', 'brown shoes', 'brown bike'] 
['blue tree', 'blue cat', 'blue car', 'brown tree', 'brown cat', 'brown car'] 
>>> 

這看起來很有趣:

>>> from pprint import pprint 
>>> pprint(list(product(prefix, suffix))) 
[('blue ', ('dog', 'shoes', 'bike')), 
('blue ', ('tree', 'cat', 'car')), 
('brown ', ('dog', 'shoes', 'bike')), 
('brown ', ('tree', 'cat', 'car'))] 

則功能映射到前綴和後綴的產品。

>>> def f(t): 
    p, s = t 
    t = product([p], s) 
    return map(''.join, t) 

>>> z = product(prefix, suffix) 
>>> y = map(f, z) 
>>> 
>>> pprint(list(map(tuple, y))) 
[('blue dog', 'blue shoes', 'blue bike'), 
('blue tree', 'blue cat', 'blue car'), 
('brown dog', 'brown shoes', 'brown bike'), 
('brown tree', 'brown cat', 'brown car')] 
>>> 

或者

>>> x = [tuple(thing) for thing in y] 

或者不map

>>> def f(t): 
    p, s = t 
    t = product([p], s) 
    return tuple(''.join(thing) for thing in t) 

>>> z = product(prefix, suffix) 
>>> y = [f(thing) for thing in z] 
>>> pprint(y) 
[('blue dog', 'blue shoes', 'blue bike'), 
('blue tree', 'blue cat', 'blue car'), 
('brown dog', 'brown shoes', 'brown bike'), 
('brown tree', 'brown cat', 'brown car')] 
>>> 
0

使用NumPy的廣播:

這裏是一個完全矢量化d實現不使用任何循環。此功能適用於任何大小的前綴/後綴輸入。

import numpy as np 

def foo(prefix, suffix): 

    ''' 
    input: 
     prefix - list 
     suffix - list of tuples 

    output: 
     numpy array 
    ''' 

    # Converting the inputs to numpy arrays 
    prefix = np.asarray(prefix) 
    suffix = np.asarray(suffix) 

    # Number of prefixes; to be used later 
    numOfPrefixes = prefix.shape[0] 
    # size of a suffix tuple size; to be used later 
    tupleSize = suffix.shape[0] 


    # Repeating the each prefix element "size of a suffix tuple size" times 
    prefix = np.repeat(prefix, tupleSize) 
    # Adding a new axis so that broadcasting is possible 
    prefix = prefix[:, np.newaxis] 

    # Repeating the original list of tuples(suffix) "number of prefixes" times 
    suffix = np.tile(suffix, (numOfPrefixes,1)) 

    return np.core.char.add(prefix, suffix) 

對於給定的輸入,這將返回:

array([['blue dog', 'blue shoes', 'blue bike'], 
    ['blue tree', 'blue cat', 'blue car'], 
    ['brown dog', 'brown shoes', 'brown bike'], 
    ['brown tree', 'brown cat', 'brown car']], 
    dtype='|S11') 

到目前爲止未使用任何循環。由於您要求最終輸出爲元組列表,因此可以使用map將上述數組轉換爲在引擎蓋下運行循環的元組列表。

list(map(tuple,foo(prefix, suffix))) 

[('blue dog', 'blue shoes', 'blue bike'), 
('blue tree', 'blue cat', 'blue car'), 
('brown dog', 'brown shoes', 'brown bike'), 
('brown tree', 'brown cat', 'brown car')]