如何仅递归地加入具有共同元素的集合,同时保留所有其他集合不变?

发布于 2025-01-09 05:02:03 字数 416 浏览 0 评论 0原文

假设我有一个定义如下的集合列表

set_list = [{1, 2}, {2, 3}, {3, 50, 60}, {70, 90}, {70, 80}, {1, 2}, {999, 888}]

我想定义一个函数,该函数接收如上所述的集合列表并输出一个新的集合列表,这样如果上面的列表作为参数传递,则输出将如下 我该

output = [{1, 2, 3, 50, 60}, {70, 80, 90}, {999, 888}]

如何实施这样的事情?

请注意,我使用列表是为了方便(我不关心集合的顺序,但我确实希望输出不包含重复项),因为集合不能是集合的元素。我知道可以用frozensets,但是写起来很麻烦。尽管如此,任何使用 freezesets 或其他方式的实现都会很棒。

Let's say I have a list of sets defined as follows

set_list = [{1, 2}, {2, 3}, {3, 50, 60}, {70, 90}, {70, 80}, {1, 2}, {999, 888}]

I want to define a function that receives a list of sets such as the above and outputs a new list of sets such that if the above list is passed as an argument the output will be as follows

output = [{1, 2, 3, 50, 60}, {70, 80, 90}, {999, 888}]

How can I go about implementing something like this?

Note that I am using a list out of convenience (I don't care about the order of the sets but I do want the output to not contain duplicates) since sets can't be elements of sets. I know I can use frozensets, but it is cumbersome to write. Nevertheless, any implementation using frozensets or otherwise will be great.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

白鸥掠海 2025-01-16 05:02:03

由于您需要递归解决方案,因此这里有一个使用 frozensets 的递归解决方案 -

set_list = [{1, 2}, {2, 3}, {3, 50, 60}, {70, 90}, {70, 80}, {1, 2}, {999, 888}]
input_list = set(frozenset(x) for x in set_list)

def merge(data):
    for x in set(data):
        for y in set(data):
            if x == y:
                continue
            if not x.isdisjoint(y):
                data.remove(x)
                data.remove(y)
                data.add(x.union(y))
                return merge(data)
    return data

print(merge(input_list))

输出 -

{frozenset({888, 999}), frozenset({80, 90, 70}), frozenset({1, 50, 3, 2, 60})}

例如,set_list 中的一个集合与 output 中的多个集合匹配代码> -

set_list = [{1, 2}, {2, 3}, {3, 50, 60}, {70, 90}, {70, 80}, {1, 2}, {999, 888}, {888, 2}]

输出 -

{frozenset({1, 2, 3, 50, 999, 888, 60}), frozenset({80, 90, 70})}

Since you wanted a recursive solution, here's a recursive solution using frozensets -

set_list = [{1, 2}, {2, 3}, {3, 50, 60}, {70, 90}, {70, 80}, {1, 2}, {999, 888}]
input_list = set(frozenset(x) for x in set_list)

def merge(data):
    for x in set(data):
        for y in set(data):
            if x == y:
                continue
            if not x.isdisjoint(y):
                data.remove(x)
                data.remove(y)
                data.add(x.union(y))
                return merge(data)
    return data

print(merge(input_list))

output -

{frozenset({888, 999}), frozenset({80, 90, 70}), frozenset({1, 50, 3, 2, 60})}

For an example case when a set in set_list matches with multiple sets in output -

set_list = [{1, 2}, {2, 3}, {3, 50, 60}, {70, 90}, {70, 80}, {1, 2}, {999, 888}, {888, 2}]

output -

{frozenset({1, 2, 3, 50, 999, 888, 60}), frozenset({80, 90, 70})}
独行侠 2025-01-16 05:02:03

我不确定这是否是最好的方法,但可能会有所帮助。

set_list = [{1, 2}, {2, 3}, {3, 50, 60}, {70, 90}, {70, 80}, {1, 2}, {999, 888}]

result = [set_list[0]]
for elem in set_list:
    if not elem.isdisjoint(result[-1]):
        result[-1].update(elem)
    else:
        _updated = False
        for i, set_ in enumerate(result):
            if not elem.isdisjoint(set_):
                result[i].update(elem)
                _updated = True
        if not _updated:
            result.append(elem)

print(result)

输出:

[{1, 2, 3, 50, 60}, {80, 90, 70}, {888, 999}]

编辑:
正如 Max Miller 指出的那样,这对于某些输入不起作用,他的解决方案更加完整。

I'm not sure if this is the best way to do it, might help nevertheless.

set_list = [{1, 2}, {2, 3}, {3, 50, 60}, {70, 90}, {70, 80}, {1, 2}, {999, 888}]

result = [set_list[0]]
for elem in set_list:
    if not elem.isdisjoint(result[-1]):
        result[-1].update(elem)
    else:
        _updated = False
        for i, set_ in enumerate(result):
            if not elem.isdisjoint(set_):
                result[i].update(elem)
                _updated = True
        if not _updated:
            result.append(elem)

print(result)

Output:

[{1, 2, 3, 50, 60}, {80, 90, 70}, {888, 999}]

Edit:
As Max Miller pointed out, this does not work for certain inputs, his solution is much more complete.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文