【问题标题】:Grouping lists within lists in Python 3在 Python 3 中的列表中对列表进行分组
【发布时间】:2011-09-25 00:16:56
【问题描述】:

我有一个这样的字符串列表:

List1 = [
          ['John', 'Doe'], 
          ['1','2','3'], 
          ['Henry', 'Doe'], 
          ['4','5','6']
        ]

我想变成这样的东西:

List1 = [
          [ ['John', 'Doe'], ['1','2','3'] ],
          [ ['Henry', 'Doe'], ['4','5','6'] ]
        ]

但我似乎在这样做时遇到了麻烦。

【问题讨论】:

    标签: python list python-3.x


    【解决方案1】:
    List1 = [['John', 'Doe'], ['1','2','3'],
             ['Henry', 'Doe'], ['4','5','6'],
             ['Bob', 'Opoto'], ['10','11','12']]
    
    def pairing(iterable):
        it = iter(iterable)
        itn = it.next
        for x in it :
            yield (x,itn())     
    
    # The generator pairing(iterable) yields tuples:  
    
    for tu in pairing(List1):
        print tu  
    
    # produces:  
    
    (['John', 'Doe'], ['1', '2', '3'])
    (['Henry', 'Doe'], ['4', '5', '6'])
    (['Bob', 'Opoto'], ['8', '9', '10'])    
    
    # If you really want a yielding of lists:
    
    from itertools import imap
    # In Python 2. In Python 3, map is a generator
    for li in imap(list,pairing(List1)):
        print li
    
    # or defining pairing() precisely so:
    
    def pairing(iterable):
        it = iter(iterable)
        itn = it.next
        for x in it :
            yield [x,itn()]
    
    # produce   
    
    [['John', 'Doe'], ['1', '2', '3']]
    [['Henry', 'Doe'], ['4', '5', '6']]
    [['Bob', 'Opoto'], ['8', '9', '10']]
    

    编辑:不需要定义生成器函数,您可以即时配对列表:

    List1 = [['John', 'Doe'], ['1','2','3'],
             ['Henry', 'Doe'], ['4','5','6'],
             ['Bob', 'Opoto'], ['8','9','10']]
    
    it = iter(List1)
    itn = it.next
    List1 = [ [x,itn()] for x in it]
    

    【讨论】:

      【解决方案2】:

      假设您总是想将成对的内部列表放在一起,这应该可以满足您的需求。

      list1 = [['John', 'Doe'], ['1','2','3'], ['Henry', 'Doe'], ['4','5','6']] 
      output = [list(pair) for pair in zip(list1[::2], list1[1::2])]
      

      它使用 zip,它为您提供元组,但如果您需要它,正如您在列表中所显示的那样,外部列表推导会执行此操作。

      【讨论】:

        【解决方案3】:

        这里是 8 行。我使用元组而不是列表,因为这是“正确”的做法:

        def pairUp(iterable):
            """
                [1,2,3,4,5,6] -> [(1,2),(3,4),(5,6)]
            """
            sequence = iter(iterable)
            for a in sequence:
                try:
                    b = next(sequence)
                except StopIteration:
                    raise Exception('tried to pair-up %s, but has odd number of items' % str(iterable))
                yield (a,b)
        

        演示:

        >>> list(pairUp(range(0)))    
        []
        
        >>> list(pairUp(range(1)))
        Exception: tried to pair-up [0], but has odd number of items
        
        >>> list(pairUp(range(2)))
        [(0, 1)]
        
        >>> list(pairUp(range(3)))
        Exception: tried to pair-up [0, 1, 2], but has odd number of items
        
        >>> list(pairUp(range(4)))
        [(0, 1), (2, 3)]
        
        >>> list(pairUp(range(5)))
        Exception: tried to pair-up [0, 1, 2, 3, 4], but has odd number of items
        

        简洁方法:

        zip(sequence[::2], sequence[1::2])
        # does not check for odd number of elements
        

        【讨论】:

        • sequence 在 Python 中具有特定的含义——可以被索引的东西。从iter,你得到一个迭代器。另外,我不确定它是否会产生性能差异,但您可能想检查循环外的try / except。性能也是为此使用itertools 的优势——它是用C 实现的。
        • @agf: try...except 在循环之外会导致不正确的行为。我的首选方法实际上是使用itertools,但我觉得很冒险。不过,感谢“序列”在 python 中具有特定含义。
        • @agf:啊抱歉,你说的完全正确。我仍然在考虑我编写的手动执行迭代协议的草稿代码,否则会引发StopIteration 异常,该异常会被吞下。啊,旧代码的幽灵。
        猜你喜欢
        • 2015-12-18
        • 2011-08-16
        • 2012-05-24
        • 1970-01-01
        • 2017-05-24
        • 1970-01-01
        • 2017-01-11
        • 2015-11-02
        • 1970-01-01
        相关资源
        最近更新 更多