首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Python-通过属性将类的实例分组在一起

Python-通过属性将类的实例分组在一起
EN

Stack Overflow用户
提问于 2018-08-07 04:28:14
回答 4查看 2.4K关注 0票数 2

我想根据属性的值将类的实例分组在一起。假设我有以下类:

代码语言:javascript
复制
class location:

    def __init__(self,x_coord,y_coord,text):
        self.x_coord=x_coord
        self.y_coord=y_coord
        self.text=text

    def __repr___(self):
        return self.text

mylist=[location(1,0,'Date'),location(5,0,'of'),location(8,0,'Entry'), location(28,0,'Date'),location(29,0,'of'),location(30,0,'Birth') ]

如果x_coord属性中的差异小于10,我希望对我的类列表进行分组,以便

代码语言:javascript
复制
mygroupedlist=[['Date','of','Entry'],['Date','of','Birth']]

有人能给我点提示吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2018-08-07 05:36:01

如果你不介意使用外部库,你可以通过使用numpy和pandas获得更好的性能。

代码语言:javascript
复制
# Create a dataframe
df = pd.DataFrame(mylist, columns=['locations'])
# Create columns representing the 'x' coords, and the 'text'
df['x'] = df['locations'].apply(lambda x: x.x_coord)
df['text'] = df['locations'].apply(lambda x: x.text)
# Create an indicator array that tells you whether the current row is within 10 of the previous row
closeness_indicator = np.isclose(df['x'], df['x'].shift(1), atol=10)
# Negate that, then take the cumulative sum to get groups:
groups = (~closeness_indicator).cumsum()
# GRoup by that array, then create lists from the grouped text:
df.groupby(groups)[text].apply(list)

输出:

代码语言:javascript
复制
1    [Date, of, Entry]
2    [Date, of, Birth]
Name: text, dtype: object
票数 1
EN

Stack Overflow用户

发布于 2018-08-07 04:50:10

这里有一个解决方案,它使用有状态函数来记住它看到的最后一项。(不要向任何函数式程序员展示这一点)。然后,我们可以在对itertools.groupby的调用中使用该函数作为关键函数

代码语言:javascript
复制
def grouper(key=lambda x: x, distance=10):
    _marker = object()
    last_seen = _marker
    flag = True
    def close_enough(item):
        nonlocal last_seen, flag
        if last_seen is _marker:
            last_seen = key(item)
            return flag
        diff = abs(key(item) - last_seen)
        last_seen = key(item)
        if diff >= distance:
            flag = not flag
        return flag
    return close_enough

[[i.text for i in g] for k, g in groupby(mylist, key=grouper(lambda x: x.x_coord))]
# [['Date', 'of', 'Entry'], ['Date', 'of', 'Birth']]
票数 0
EN

Stack Overflow用户

发布于 2018-08-07 05:02:49

我的尝试是,使用计数器,每当有大于或等于distance的变化时,计数器就会增加。这样就可以轻松地将此生成器提供给groupby

代码语言:javascript
复制
def gen(lst, distance=10):
    counter = 0
    for cur, nxt in zip(lst[::1], lst[1::1]):
        yield counter, cur
        if abs(cur.x_coord - nxt.x_coord) >= distance:
            counter += 1
    yield counter, nxt

myGroupedList = [list(i[1] for i in g) for _, g in groupby(gen(mylist), lambda v: v[0])]
print(myGroupedList)

打印:

代码语言:javascript
复制
[[Date, of, Entry], [Date, of, Birth]]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51715184

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档