Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/308.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_Set - Fatal编程技术网

Python 有没有一条捷径可以到达;“剩余”;有什么区别?

Python 有没有一条捷径可以到达;“剩余”;有什么区别?,python,set,Python,Set,我遇到了这个问题: 给定一个可数i,两个不相交的集合a和b(其中通常a和b包含的元素远远多于i)从a中删除i中找到的所有元素,并将i中未被a共享的所有元素添加到b 例如: i = [0, 3] a = {1, 2, 3, 4} b = {5, 6, 7, 8} 应该导致 a = {1, 2, 4} b = {0, 5, 6, 7, 8} 根据该图,灰色子集应为空。操作完成后,我希望浅蓝色子集加入到b,黄色重叠部分从a中删除 为了解决这个问题,我编写了以下Python函数: def foo(

我遇到了这个问题:

给定一个可数
i
,两个不相交的集合
a
b
(其中通常
a
b
包含的元素远远多于
i
)从
a
中删除
i
中找到的所有元素,并将
i
中未被
a
共享的所有元素添加到
b

例如:

i = [0, 3]
a = {1, 2, 3, 4}
b = {5, 6, 7, 8}
应该导致

a = {1, 2, 4}
b = {0, 5, 6, 7, 8}

根据该图,灰色子集应为空。操作完成后,我希望浅蓝色子集加入到
b
,黄色重叠部分从
a
中删除

为了解决这个问题,我编写了以下Python函数:

def foo(i, a, b):
    set_i = set(i)
    b |= set_i - a
    a -= set_i
这是可行的,但它不是很漂亮,仍然可以做两次事情(a和set_i的区别)

什么方法更有效?

试试:

def foo(i,a,b):
a-=集合(i)
b |=a

难道你不能像你描述的那样简单地完成它吗:

def foo(i,a,b):
对于el in i:
如果el在a中:
a、 移除(el)
其他:
b、 加(el)
我不会在适当的地方对a和b进行变异,特别是因为它们是作为函数的参数提供的,所以安全的版本应该是

def foo(i,a,b):
a_new=a.copy()
b_new=b.copy()
对于el in i:
如果el在a中:
a_新。移除(el)
其他:
b_新添加(el)
返回a_new,b_new
在一般情况下,它会更有效,因为
i
是一个iterable(可能是一个实际的迭代器),您只需对它迭代一次。如果您将它转换为一个集合,那么在内部它将被迭代一次,然后对于每个集合操作,至少重复两次

您还可以使用
itertools
中的
groupby
,如下所示:

从itertools导入groupby
def foo(i、a、b):
对于in_a,i_group in groupby(i,key=lambda x:x in a):
如果在a中:
a-=集合(i_组)
其他:
b |=集合(i|u群)

这根本不是等价的,它可以将i的元素移动到a和b,但也可以将以前在a中的所有元素移动到b中。你能给我们一些输入和预期输出的例子吗?我看不出差异被计算了两次:
i-a
不是
a-i
的简单补充。对不起,我想我不明白“不容易补足”这一部分。这两条线的差异是如何计算出来的?我建议你做一个维恩图,三个重叠的圆圈,勾勒出你想要的结果。我想,b的所有元素都应该保留,即使它们在b和a的交叉点。这让我意识到我忘了指定a和b应该是不相交的。我可以这样做,但我假设只迭代一次并不能弥补从a中删除并添加到b的额外工作,而不是通过集合操作。我也承认改变输入参数不是一种很好的风格,但这正是我想要做的,在每次调用中复制它们的内容并不能解决这个问题。groupby与我想象的很接近,但在我看来,调用这个lambda只是额外的工作,而且该函数要求输入迭代器按键排序。添加到a和从b中删除看起来是额外的工作,但在内部,set operations逐项工作,因此只有您的代码看起来效率较低,但是实际执行的时间更快,你可以计时,看看什么更有效率。同意,看起来它们的工作原理是一样的。但是,现在我不确定是否显式检查“a中的el”是额外的工作,因为set.remove中可能已经有类似的内容了。因此,在python中,这可能无法以绝对的效率完成。@TheodorStraube我刚刚注意到我的第一个解决方案有一个bug-如果同一元素在
I
a
中多次出现,它的第一次出现将从
a
中删除,但随后的元素将添加到
b
,因为它将不再出现在
a
中。使用
groupby
的最后一个解决方案工作正常,因为在迭代组之前执行组生成。