5

我觉得 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']}

有没有更好的办法?

4

2 回答 2

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)

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

于 2013-03-23T06:09:01.103 回答
1

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

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

所以这和你上面的例子一样,但是变成了一个函数,返回iteritems你建立的查找表的。

于 2013-04-30T21:36:36.290 回答