Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 基于共存规则将列表拆分为多个组_Python_Python 3.x_Set_Set Theory - Fatal编程技术网

Python 基于共存规则将列表拆分为多个组

Python 基于共存规则将列表拆分为多个组,python,python-3.x,set,set-theory,Python,Python 3.x,Set,Set Theory,我想根据“排除”规则创建字符串(或对象)组,即哪些项可以存在或与其他项“对话” 例如,假设我有一个姓名列表: names=['proxy','s1','s2','queue','w1'] 然后我说,'proxy'可以与's1'和's2'对话,但是's1'不能与's2'对话(这应该是相互的)。 我可以将这些规则和名称表示为对象列表: proxy = {'name': 'proxy', 'exclude': [q, 'w1']} s1 = {'name': 's1', 'exclude': ['s

我想根据“排除”规则创建字符串(或对象)组,即哪些项可以存在或与其他项“对话”

例如,假设我有一个姓名列表:

names=['proxy','s1','s2','queue','w1']
然后我说,
'proxy'
可以与
's1'
's2'
对话,但是
's1'
不能与
's2'
对话(这应该是相互的)。 我可以将这些规则和名称表示为对象列表:

proxy = {'name': 'proxy', 'exclude': [q, 'w1']}
s1 = {'name': 's1', 'exclude': ['s2', 'w1']}
s2 = {'name': 's2', 'exclude': ['s1', 'w1']}
q = {'name': 'queue', 'exclude': ['proxy']}
w1 = {'name': 'w1', 'exclude': ['proxy', 's1', 's2']}
在这里,我希望最后有5个小组:

[
  ['proxy', 's1'],
  ['proxy', 's2'],
  ['s1', 'queue'],
  ['s2', 'queue'],
  ['queue', 'w1']
]
我曾尝试在每个“排除”的完整名称列表中使用
set.difference
,然后删除任何相等的集合,但这还不够,例如,对于第一项“proxy”,我最终会得到一组['proxy',s1',s2',但ofc“s1”和“s2”不能在一起

我很难找到这个问题的解决方案,但我有一种感觉,它是或类似于常见的数学/集合论问题

额外信息: 正如@MrFuppes很好地提到的,连接是双向的(即,如果X排除Z,那么Z应该排除X),这应该是假设的,如果可能的话可以推断。这是为了让用户更简单,因此他们不必显式地声明这两个规则。
可能是因为我的“规则模式”不是从用户那里收集数据以解决问题的最佳方式,如果有更好的方式,我完全支持它。

肯定不是有史以来最漂亮的Python,但它可以做到这一点。我冒昧地在一个规则字典中收集规则,并将q重命名为队列以保持一致性。如果这是个问题,我们会找到解决办法

rules = {'proxy':{'name': 'proxy', 'exclude': ['queue', 'w1']},
         's1': {'name': 's1', 'exclude': ['s2', 'w1']},
         's2':{'name': 's2', 'exclude': ['s1', 'w1']},
         'queue': {'name': 'queue', 'exclude': ['proxy']},
         'w1': {'name': 'w1', 'exclude': ['proxy', 's1', 's2']}}
names = ['proxy', 's1', 's2', 'queue', 'w1']
现在是代码本身。我首先深度复制规则dict,因为我将添加已列为排除的连接,不想弄乱原始规则集。其余的都很简单,所以我不会对此做太多评论:通过删除连接器本身和所有阻止的连接来获取所有允许的名称,将每个连接添加到连接列表中,并将连接器作为阻止元素添加到所有受影响的连接中,以避免重复条目

import copy
conns = []
working_rules = copy.deepcopy(rules)
for item in names:
    tmp_names = names.copy()
    tmp_names.remove(item)
    allowed = [el for el in tmp_names if el not in working_rules[item]['exclude']]
    for el in allowed:
        conns.append([item, el])
        working_rules[el]['exclude'].append(item)

给定预期的输出,输入规则是“不完整的”,这意味着必须推断排除的相互性——正如Lukas Thaler在他的文章中所示。然后,推断出的排除规则将取决于输入名称的顺序。使用
集合的简化版本可能如下所示:

excl={'proxy':['queue','w1'],
's1':['s2','w1'],
's2':['s1','w1'],
“队列”:[“代理”],
'w1':['proxy','s1','s2']}
名称=['proxy','s1','s2','queue','w1']
结果=[]
对于名称中的n:
对于集合中的i(名称)-集合(不包括[n]+[n]):
result.append([n,i])
excl[i]。追加(n)
打印(结果)
#[['proxy','s1'],
#['proxy','s2'],
#['s1','队列'],
#['s2','队列'],
#['queue','w1']]
更新的排除规则现在将被删除

{'proxy': ['queue', 'w1'],
    's1': ['s2', 'w1', 'proxy'],
    's2': ['s1', 'w1', 'proxy'],
 'queue': ['proxy', 's1', 's2'],
    'w1': ['proxy', 's1', 's2', 'queue']}

编辑#1

如果我没有弄错的话,先验地假设双向通信会使事情变得更容易(同时也有助于首先明确规则的定义)。示例:给定对象
a、b、c
,可以说
a
应该与
b
通信,反之亦然<代码>a
也应与
c
通信,但反之亦然<代码>b不应与
c
通信,反之亦然。那将使

objs=['a','b','c']
excl={'a':[],
“b”:[c'],
'c':['a','b']}
连接=[[o,i]用于objs中的o,用于集合中的i(objs)-集合(不包括[o]+[o])]
打印(连接)
#[a'、[b']、[a'、[c']、[b'、[a']

编辑#2

然后可以通过将连接列表分为双向和单向组件来简化连接列表,例如

conn_group={‘双向’:[],‘单向’:[]
对于c输入连接:
rev_c=列表(反向(c))
如果版本c不在连接中:
连接分组[‘单向’]。附加(c)
如果rev_c在连接中,而不是rev_c在连接中分组[“双向”]:
连接分组['bidirectional'].附加(c)
打印(连接分组)
#{'bidirectional':[['a','b']],'unidirectional':[['a','c']]}

如果通信节点的数量越来越多,可能需要找到更有效的算法。

这很酷。事实上,能够推断相互性将是一个好处,让用户更容易陈述他们的规则。@jramm实际上,这让我有点担心这个问题,因为最后的规则基本上说所有连接都是单向的。我认为这里使用的规则推断方案排除了双向性。首先假设双向性,并通过一套完整的规则故意将其排除在外,可能更普遍适用。有没有更好的规则模式?我的主要想法是让用户不需要计算出他们需要什么“组”,而是允许他们(尽可能简单地)说“X不能和Y和Z说话”,“Z也不能和K说话”。应该假设双向性,这样他们就不必显式地声明它。我想我们可以通过推断初始循环中的额外排除规则来消除对名称顺序的依赖。这将是性能的一半,但由于列表的大小相对较小(我预计不会超过10-20个项目),这在很大程度上可以忽略不计@jramm,对其进行了编辑以显示我的意思。希望我明白了;-)好东西。修改初始数据的模式是完全可能的。我完全可以控制它,因此我们可以选择最优化的解决方案(最优化的是用户最容易使用的模式,不一定是最高效或简洁的模式)。我注意到这个解决方案的一点是,它是非优化的,因为它总是成对创建组。例如,假设我们有一个包含3个名称和非排除项的列表。最优s