代码之家  ›  专栏  ›  技术社区  ›  froadie

如何使用列表理解将元组的元组转换为一维列表[[副本]

  •  28
  • froadie  · 技术社区  · 16 年前

    我有一个元组-例如:

    tupleOfTuples = ((1, 2), (3, 4), (5,))
    

    我想把它转换成一个平面的,一维的,按顺序排列的所有元素的列表:

    [1, 2, 3, 4, 5]
    

    我一直在尝试用列表理解来完成这个任务。但我好像想不通。我可以通过一个for each循环来完成它:

    myList = []
    for tuple in tupleOfTuples:
       myList = myList + list(tuple)
    

    一个简单的 [list(tuple) for tuple in tupleOfTuples]

    [*list(tuple) for tuple in tupleOfTuples]
    

    或

    [*(list(tuple)) for tuple in tupleOfTuples]
    

    7 回复  |  直到 16 年前
        1
  •  70
  •   SilentGhost    16 年前

    它通常被称为展平嵌套结构。

    >>> tupleOfTuples = ((1, 2), (3, 4), (5,))
    >>> [element for tupl in tupleOfTuples for element in tupl]
    [1, 2, 3, 4, 5]
    

    >>> import timeit
    >>> it = lambda: list(chain(*tupleOfTuples))
    >>> timeit.timeit(it)
    2.1475738355700913
    >>> lc = lambda: [element for tupl in tupleOfTuples for element in tupl]
    >>> timeit.timeit(lc)
    1.5745135182887857
    

    预计到达时间 :请不要使用 tuple 作为变量名,它是内置的。

        2
  •  41
  •   Community Mohan Dere    9 年前

    只是使用 sum

    >>> tupleOfTuples = ((1, 2), (3, 4), (5,))
    >>> sum(tupleOfTuples, ())
    (1, 2, 3, 4, 5)
    >>> list(sum(tupleOfTuples, ())) # if you really need a list
    [1, 2, 3, 4, 5]
    

    如果你有很多元组,使用 list comprehension chain.from_iterable 为了防止


    微观基准:

      • 短元组的长元组

        $ python2.6 -m timeit -s 'tot = ((1, 2), )*500' '[element for tupl in tot for element in tupl]'
        10000 loops, best of 3: 134 usec per loop
        $ python2.6 -m timeit -s 'tot = ((1, 2), )*500' 'list(sum(tot, ()))'
        1000 loops, best of 3: 1.1 msec per loop
        $ python2.6 -m timeit -s 'tot = ((1, 2), )*500; from itertools import chain; ci = chain.from_iterable' 'list(ci(tot))'
        10000 loops, best of 3: 60.1 usec per loop
        $ python2.6 -m timeit -s 'tot = ((1, 2), )*500; from itertools import chain' 'list(chain(*tot))'
        10000 loops, best of 3: 64.8 usec per loop
        
      • $ python2.6 -m timeit -s 'tot = ((1, )*500, (2, )*500)' '[element for tupl in tot for element in tupl]'
        10000 loops, best of 3: 65.6 usec per loop
        $ python2.6 -m timeit -s 'tot = ((1, )*500, (2, )*500)' 'list(sum(tot, ()))'
        100000 loops, best of 3: 16.9 usec per loop
        $ python2.6 -m timeit -s 'tot = ((1, )*500, (2, )*500); from itertools import chain; ci = chain.from_iterable' 'list(ci(tot))'
        10000 loops, best of 3: 25.8 usec per loop
        $ python2.6 -m timeit -s 'tot = ((1, )*500, (2, )*500); from itertools import chain' 'list(chain(*tot))'
        10000 loops, best of 3: 26.5 usec per loop
        
      • 短元组的长元组

        $ python3.1 -m timeit -s 'tot = ((1, 2), )*500' '[element for tupl in tot for element in tupl]'
        10000 loops, best of 3: 121 usec per loop
        $ python3.1 -m timeit -s 'tot = ((1, 2), )*500' 'list(sum(tot, ()))'
        1000 loops, best of 3: 1.09 msec per loop
        $ python3.1 -m timeit -s 'tot = ((1, 2), )*500; from itertools import chain; ci = chain.from_iterable' 'list(ci(tot))'
        10000 loops, best of 3: 59.5 usec per loop
        $ python3.1 -m timeit -s 'tot = ((1, 2), )*500; from itertools import chain' 'list(chain(*tot))'
        10000 loops, best of 3: 63.2 usec per loop
        
      • $ python3.1 -m timeit -s 'tot = ((1, )*500, (2, )*500)' '[element for tupl in tot for element in tupl]'
        10000 loops, best of 3: 66.1 usec per loop
        $ python3.1 -m timeit -s 'tot = ((1, )*500, (2, )*500)' 'list(sum(tot, ()))'
        100000 loops, best of 3: 16.3 usec per loop
        $ python3.1 -m timeit -s 'tot = ((1, )*500, (2, )*500); from itertools import chain; ci = chain.from_iterable' 'list(ci(tot))'
        10000 loops, best of 3: 25.4 usec per loop
        $ python3.1 -m timeit -s 'tot = ((1, )*500, (2, )*500); from itertools import chain' 'list(chain(*tot))'
        10000 loops, best of 3: 25.6 usec per loop
        

    • 总和
    • list(chain.from_iterable(x)) 如果外部元组较长,则速度更快。
        3
  •  13
  •   Jochen Ritzel    16 年前

    将元组链接在一起:

    from itertools import chain
    print list(chain(*listOfTuples))
    

    如果你熟悉 itertools list

        4
  •  9
  •   Donald Miner    16 年前

    我喜欢在这种情况下使用reduce(这就是reduce的用途!)

    lot = ((1, 2), (3, 4), (5,))
    print list(reduce(lambda t1, t2: t1 + t2, lot))
    
     > [1,2,3,4,5]
    
        5
  •  9
  •   Craig Trader    16 年前

    这些答案中的大多数只适用于单一水平的扁平化。要获得更全面的解决方案,请尝试以下方法(从 http://rightfootin.blogspot.com/2006/09/more-on-python-flatten.html ):

    def flatten(l, ltypes=(list, tuple)):
        ltype = type(l)
        l = list(l)
        i = 0
        while i < len(l):
            while isinstance(l[i], ltypes):
                if not l[i]:
                    l.pop(i)
                    i -= 1
                    break
                else:
                    l[i:i + 1] = l[i]
            i += 1
        return ltype(l)
    
        6
  •  4
  •   Mad Scientist    16 年前

    itertools.chain

    >>> tupleOfTuples = ((1, 2), (3, 4), (5,))
    >>> from itertools import chain
    >>> [x for x in chain.from_iterable(tupleOfTuples)]
    [1, 2, 3, 4, 5]
    
        7
  •  4
  •   jsbueno    16 年前

    对于多级可读代码:

    def flatten(bla):
        output = []
        for item in bla:
            output += flatten(item) if hasattr (item, "__iter__") or hasattr (item, "__len__") else [item]
        return output
    

    我无法把它放在一行中(即使到目前为止,也仍然可读)