我觉得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']}
有更好的方法吗?
答案 0 :(得分:3)
我还将这个问题发布到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)
我打算删除我的问题,但我不妨把它留在这里以防万一有人偶然发现它寻找信息。
答案 1 :(得分:1)
如果您想要与groupby
大致相同的API,可以使用:
def groupby2(iterable, keyfunc):
lookup = collections.defaultdict(list)
for item in iterable:
lookup[keyfunc(item)].append(item)
return lookup.iteritems()
这与上面的例子相同,但是变成了一个函数,返回你构建的查找表的iteritems
。