【问题标题】:Grouping items by a key?按键对项目进行分组?
【发布时间】:2013-03-12 15:07:45
【问题描述】:

我觉得 Python 应该有一个内置函数来执行此操作。获取项目列表并将它们转换为字典,将键映射到具有该键的项目列表。

这很容易做到:

# using defaultdict
lookup = collections.defaultdict(list)
for item in items:
    lookup[key(item)].append(item)

# or, using plain dict
lookup = {}
for item in items:
    lookup.setdefault(key(item), []).append(item)

但这已经足够频繁地使用内置函数了。我可以自己实现它,如下所示:

def grouped(iterable, key):
    result = {}
    for item in iterable:
        result.setdefault(key(item), []).append(item)
    return result

lookup = grouped(items, key)

这在几个重要方面与itertools.groupby 不同。要从groupby 获得相同的结果,您必须这样做,这有点难看:

lookup = dict((k, list(v)) for k, v in groupby(sorted(items, key=key), key))

一些例子:

>>> items = range(10)
>>> grouped(items, lambda x: x % 2)
{0: [0, 2, 4, 6, 8], 1: [1, 3, 5, 7, 9]}

>>> items = 'hello stack overflow how are you'.split()
>>> grouped(items, len)
{8: ['overflow'], 3: ['how', 'are', 'you'], 5: ['hello', 'stack']}

有没有更好的办法?

【问题讨论】:

  • 我不明白这是一个“足够频繁的用例”。我很少使用它,当我不得不使用它时,使用defaultdict 简直是完美的。 AFAIK 没有任何内置功能可以自行完成。
  • 你可能是对的,但我的一部分认为这对于内置函数和 groupby 一样有效。

标签: python collections group-by iterable


【解决方案1】:

我也将这个问题发布到了 comp.lang.python,大家的共识似乎是这实际上并不常见,不足以保证内置函数。因此,最好使用显而易见的方法。它们工作并且可读。

# using defaultdict
lookup = collections.defaultdict(list)
for item in items:
    lookup[key(item)].append(item)

# or, using plain dict
lookup = {}
for item in items:
    lookup.setdefault(key(item), []).append(item)

我打算删除我的问题,但我不妨把它留在这里,以防有人偶然发现它寻找信息。

【讨论】:

  • 请参阅下面我的回答,了解如何提取函数以执行与上述相同的操作,但使用与 groupby 大致相同的 API。
【解决方案2】:

如果您想要 API 与 groupby 大致相同的东西,您可以使用:

def groupby2(iterable, keyfunc):
    lookup = collections.defaultdict(list)
    for item in iterable:
        lookup[keyfunc(item)].append(item)
    return lookup.iteritems()

所以这与您上面的示例相同,但被制成一个函数,返回您已构建的查找表的 iteritems

【讨论】:

    猜你喜欢
    • 2021-11-14
    • 1970-01-01
    • 1970-01-01
    • 2022-01-15
    • 2021-09-24
    • 2012-05-23
    • 2018-07-16
    • 2014-10-27
    • 1970-01-01
    相关资源
    最近更新 更多