【问题标题】:How can I group the items in a list in sorted order?如何按排序顺序对列表中的项目进行分组?
【发布时间】:2015-06-04 07:06:51
【问题描述】:

我有一些由这样的元组组成的列表

one = [(4, 'a'), (3, 'b'), (2, 'c'), (3, 'd'), (5, 'e'), (6, 'f')]

我想根据该整数对列表一中的项目进行分组,以创建具有这样输出的新数组

final = [(g1, 2, ['c']), (g2, 3, ['b','d']), (g3, 4, ['a']), (g4, 5, ['e']), (g5, 6, ['f'])]

我不知道创建最终列表。 python是如何做到的?任何想法,将不胜感激。谢谢。

注意: g1、g2 等只是一些带增量的字符串。

【问题讨论】:

  • 订单对您重要吗?什么是g1g2...?
  • 是的,这让我很困惑。我应该订购清单。而 g1, g2, g3 只是一些具有增量值的字符串。感谢您的帮助。
  • 2, ['a']5, ['f'] 是从哪里来的?
  • 那是我的错,我的意思是 (g1, 2, ['c']) 和 (g5, 6, ['f'])。已编辑。

标签: python list tuples grouping


【解决方案1】:

由于要对输出进行排序,所以可以根据第一个元素对原始列表进行排序

>>> first = lambda x: x[0]
>>> one_sorted = sorted(one, key=first)

然后你可以使用itertools.groupby根据第一个元素对元素进行分组,像这样

groupby(one_sorted, first)

由于您想按升序为组分配数字,您可以像这样用enumerate 包装它

enumerate(groupby(one_sorted, first), 1)

然后你可以在for 循环中unpack enumerate 的结果,像这样

for index, (item, group) in enumerate(groupby(one_sorted, first), 1)

现在您只需构建结果列表。您可以使用list comprehension 来执行此操作,就像这样

>>> from itertools import groupby
>>> [(index, item, [j[1] for j in group])
...     for index, (item, group) in enumerate(groupby(one_sorted, first), 1)]
[(1, 2, ['c']), (2, 3, ['b', 'd']), (3, 4, ['a']), (4, 5, ['e']), (5, 6, ['f'])]

[j[1] for j in group] 实际上是迭代分组的项并获取第二项,即实际的字符串。


或者,您可以将字典中的元素分组,如下所示

>>> groups = {}
>>> for number, string in one:
...     groups.setdefault(number, []).append(string)
...     
... 
>>> groups
{2: ['c'], 3: ['b', 'd'], 4: ['a'], 5: ['e'], 6: ['f']}

然后在排序后的字典上应用enumerate,像这样

>>> [(index, number, groups[number])
...     for index, number in enumerate(sorted(groups), 1)]
[(1, 2, ['c']), (2, 3, ['b', 'd']), (3, 4, ['a']), (4, 5, ['e']), (5, 6, ['f'])]

【讨论】:

  • [(index, item, [j[1] for j in group]) for index, (item, group) in enumerate(groupby(one_sorted, first), 1)]魅力。但我不明白,你像专业人士一样构建了这个列表,哈哈。谢谢。
  • 嗨,很抱歉,这会是 OOT,但我想知道如果我们不对第一个列表进行排序怎么办?我的意思是,我们只是“分组”该列表。这怎么可能?
【解决方案2】:

您可以使用默认字典对项目进行分组:

from collections import defaultdict

# create dictionary # {2: ['c'], 3: ['b', 'd'], 4: ['a'], ...}
groups = defaultdict(list)
for k,v in one:
    groups[k].append(v)

# create sorted list [(1, (2, ['c'])), (2, (3, ['b', 'd'])), (3, (4, ['a'])), ...]
lists = enumerate(sorted(list(groups.items())), 1)

注意:上面产生了一个枚举器,它是类似生成器的对象(see here)。如果要转换为普通列表,只需将最后一行替换为:

lists = [(i,k,v) for i,(k,v) in enumerate(sorted(list(groups.items())), 1)]

【讨论】:

  • 很有希望,我打印了列表并给了我错误“”。谢谢
  • @SonicMaster 这不是错误。它正在打印枚举器对象引用。但是,如果您需要一个列表,我已经更新了答案以显示如何转换为普通列表。
【解决方案3】:

我认为最好的解决方案是从 int -> 列表创建字典。遍历原始列表,如果 int 是键,则只需将其添加到其列表中,否则使用其值创建一个列表并将其添加到字典中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多