Python:按投影值的相等性将列表分组为子列表

2024-10-03 15:35:43 发布

您现在位置:Python中文网/ 问答频道 /正文

有没有一种很好的python方法可以将一个列表分组成一个列表列表,其中每个内部列表只包含那些具有相同投影的元素,这些元素由用户定义为一个函数?

示例:

>>> x = [0, 1, 2, 3, 4, 5, 6, 7]
>>> groupby(x, projection=lambda e: e % 3)
[[0, 3, 6], [1, 4, 7], [2, 5]]

我不关心投影本身,只是如果它对某些元素是相等的,那么这些元素最终必须在同一个子列表中。

我基本上在寻找与haskell函数^{}等价的python:

Prelude> import GHC.Exts
Prelude GHC.Exts> groupWith (`mod` 3) [0..7]
[[0,3,6],[1,4,7],[2,5]]

Tags: 方法lambda函数用户元素示例列表定义
3条回答

标准库中的itertools模块包含一个^{}函数,该函数应该执行您想要的操作。

请注意,到groupby()的输入应该按组键进行排序,以便只生成一个组,但是使用相同的键函数进行排序很容易。所以,如果你的关键函数(投影)是看一个数字是不是偶数,它会是这样的:

from itertools import groupby
x = [0, 1, 2, 3, 4, 5, 6, 7]

def projection(val):
    return val % 3

x_sorted = sorted(x, key=projection)
x_grouped = [list(it) for k, it in groupby(x_sorted, projection)]    
print(x_grouped)

[[0, 3, 6], [1, 4, 7], [2, 5]]

注意,虽然这个版本只使用标准的Python特性,但是如果您处理的值可能超过100.000,那么您应该研究panda(参见@ayhan的答案)

不需要分类。

from collections import defaultdict

def groupby(iterable, projection):
    result = defaultdict(list)
    for item in iterable:
        result[projection(item)].append(item)
    return result

x = [0, 1, 2, 3, 4, 5, 6, 7]
groups = groupby(x, projection=lambda e: e % 3)
print groups
print groups[0]

输出:

defaultdict(<type 'list'>, {0: [0, 3, 6], 1: [1, 4, 7], 2: [2, 5]})
[0, 3, 6]

pandas版本如下:

import pandas as pd
x = [0, 1, 2, 3, 4, 5, 6, 7]
pd.Series(x).groupby(lambda t: t%3).groups
Out[13]: {0: [0, 3, 6], 1: [1, 4, 7], 2: [2, 5]}

或者

pd.Series(x).groupby(lambda t: t%3).groups.values()
Out[32]: dict_values([[0, 3, 6], [1, 4, 7], [2, 5]])

相关问题 更多 >