【问题标题】:Converting a Tuples List into a nested List using Python使用 Python 将元组列表转换为嵌套列表
【发布时间】:2010-12-23 18:01:50
【问题描述】:

我想使用 Python 将元组列表转换为嵌套列表。我该怎么做?

我有一个排序的元组列表(按第二个值排序):

[(1, 5),  (5, 4), (13, 3), (4, 3), (3, 2), (14, 1), (12, 1), 
 (10, 1), (9, 1), (8, 1),  (7, 1), (6, 1), (2, 1)]

现在我希望它像这样(第二个值被忽略并嵌套在列表中):

[ [1], [5], [13, 4], [3], [14, 12, 10, 9, 8, 7, 6, 2] ]

我在这里看到了map 用于此类事情的其他线程,但我并不完全理解它。任何人都可以提供有关“正确”python 执行此操作的方法的见解吗?

【问题讨论】:

    标签: python list nested tuples


    【解决方案1】:

    不知道这对于更大的集合会有多快,但你可以这样做:

    input = [
        (1,  5), (5,  4), (13, 3), (4, 3), (3, 2), (14, 1),
        (12, 1), (10, 1), (9,  1), (8, 1), (7, 1), (6,  1),
        (2,  1)
    ]
    
    output = [[] for _ in xrange(input[0][1])]
    for value, key in input:
        output[-key].append(value)
    
    print output # => [[1], [5], [13, 4], [3], [14, 12, 10, 9, 8, 7, 6, 2]]
    

    【讨论】:

    • 你假设 len(output) 应该匹配最高的键值,并且键值总是连续的。
    • 是的,我假设 OP 希望 inputoutput 中的索引匹配 - 所以如果你采取例如(3, 2)input 中,然后output[-2] 将是一个空列表。很难说只有一个数据集。
    【解决方案2】:
    from operator import itemgetter
    from itertools import groupby
    
    lst = [(1, 5),  (5, 4), (13, 3), (4, 3), (3, 2), (14, 1),
           (12, 1), (10, 1), (9, 1), (8, 1),  (7, 1), (6, 1), (2, 1)]
    
    result = [[x for x, y in group]
              for key, group in groupby(lst, key=itemgetter(1))]
    

    groupby(lst, key=itemgetter(1)) 生成lst 的连续元素组,其中所有元素都具有相同的第一个(从零开始计数)项。 [x for x, y in group] 保留每个组内每个元素的第 0 项。

    【讨论】:

    • 我喜欢这个。简单且无需映射。
    • 可能sort 是一个整数列表,而不是一个二元组列表。
    • groupby 需要对lst 进行排序:lst.sort(key=itemgetter(1))
    • 正如我所说.. 这是一个错字对不起。将错误的列表放入函数中。但是感谢快速的 cmets :)
    【解决方案3】:

    这有点复杂,但你可以使用 itertools.groupby 函数来完成:

    >>> lst = [(1, 5),  (5, 4), (13, 3), (4, 3), (3, 2), (14, 1), (12, 1), 
     (10, 1), (9, 1), (8, 1),  (7, 1), (6, 1), (2, 1)]
    >>> from operator import itemgetter 
    >>> import itertools
    >>> [map(itemgetter(0), group) for (key,group) in itertools.groupby(lst, itemgetter(1))]
    [[1], [5], [13, 4], [3], [14, 12, 10, 9, 8, 7, 6, 2]]
    >>> 
    

    说明: groupby 为每个组返回一个迭代器,其中组被定义为一系列条目,这些条目具有由作为单独参数传递的函数返回的相同值。 itemgetter(1) 生成一个函数,该函数在使用参数 x 调用时返回 x[1]。 由于 groupby 迭代器返回两个值 - 使用的键和作为元组的原始值的序列,然后我们需要去除每个元组中的第二个值,这就是 map(itemgetter(0), group) 所做的。

    【讨论】:

    • 也很好,但你的最后一行令人困惑,因为我需要学习一点映射的东西。我认为它几乎与罗伯托发布的相同。不过谢谢!
    【解决方案4】:

    也许不是最pythonesque的答案,但这有效:

    d = {}
    
    a = [(1,5), (5,4), (13,3), (4,3), (3,2), (14,1), (12,1)]
    
    for value in a:
         if value[0] not in d:
             d[ value[0] ] = []
         d[ value[0] ].append( a[1] )
    
    print d.values()
    

    【讨论】:

    • 我会用 setdefault() 来改进这一点,而不是检查 value[0] not in d
    【解决方案5】:

    简单的解决方案:

    n_list = []
    c_snd = None
    for (fst, snd) in o_list:
      if snd == c_snd: n_list[-1].append(fst)
      else:
        c_snd = snd
        n_list.append([fst])
    

    说明:使用c_snd 存储元组的当前第二部分。如果情况发生变化,请在n_list 中为这个新的第二个值创建一个新列表,从fst 开始,否则将fst 添加到n_list 中的最后一个列表中。

    【讨论】:

      猜你喜欢
      • 2017-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-06
      • 1970-01-01
      • 2020-02-28
      相关资源
      最近更新 更多