列表和元组之间的连接/分发

时间:2017-03-04 15:37:13

标签: python list tuples list-comprehension

我有以下示例。

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循环的任何方法吗?

3 个答案:

答案 0 :(得分: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))

答案 1 :(得分:0)

如果没有嵌套(明确或其他方式),无法找到任何获得四个单独教堂的方法。

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

答案 2 :(得分:0)

使用Numpy Broadcasting:

这是一个完全向量化的实现,不使用任何循环。此函数适用于任何大小的前缀/后缀输入。

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