【发布时间】: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