【问题标题】:concatenating/distributing between lists and tuples在列表和元组之间连接/分配
【发布时间】:2017-07-24 16:21:15
【问题描述】:

我有以下示例。

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 循环?

【问题讨论】:

    标签: python list tuples list-comprehension


    【解决方案1】:

    使用嵌套列表推导:

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

    【讨论】:

    • 这看起来很棒 - 我试图直观地理解这一点以及如何从左到右或从右到左阅读它。你有等效的 for 循环构造吗?
    • @laszlopanaflex 已更新!
    • 谢谢-这是我很难理解python如何解释这些嵌套语句的地方-其他示例建议从左到右,在这种情况下,我预计会有一个问题为“j”尚未定义。
    【解决方案2】:

    没有嵌套(显式或其他方式),看不到任何获得四个独立元组的​​方法。

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

    【讨论】:

      【解决方案3】:

      使用 Numpy 广播:

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

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

      【讨论】:

        猜你喜欢
        • 2014-02-15
        • 1970-01-01
        • 2012-05-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-11
        相关资源
        最近更新 更多