Python:&= 运算符

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28395503/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 03:12:54  来源:igfitidea点击:

Python: &= operator

pythonpython-2.7python-3.xset

提问by OhMyGosh

When I try to or/and two sets using &=and |=operator, I got some weird result.

当我尝试使用&=and|=运算符对或/和两组进行操作时,得到了一些奇怪的结果。

s1 = {1,2,3}
s2 = {2,3,4}
tmp = s1
tmp &= s2 

As expected, tmp will be {2,3}, but I don't know why s1also changed it value to {2,3}.

正如预期的那样,tmp 将是 {2,3},但我不知道为什么s1也将其值更改为 {2,3}。

However, if I do:

但是,如果我这样做:

tmp = tmp & s2

Then, s1will be unchanged! Can anyone explain for me what happens underneath &=operator?

那么,s1将一成不变!谁能为我解释在&=操作员下面发生了什么?

采纳答案by falsetru

&=(set.__iadd__)for setis implemented differently with &(set.__add).

&=( set.__iadd__)forset&( set.__add) 的实现方式不同。

set &= ...is implemented using set.intersection_updatewhich update the set in-place.

set &= ...使用set.intersection_updatewhich 就地更新集合来实现。



Relevant CPython code (Object/setobject.c):

相关 CPython 代码 ( Object/setobject.c):

set_iand(PySetObject *so, PyObject *other)
{
    PyObject *result;

    if (!PyAnySet_Check(other))
        Py_RETURN_NOTIMPLEMENTED;
    result = set_intersection_update(so, other); // <----
    if (result == NULL)
        return NULL;
    Py_DECREF(result);
    Py_INCREF(so);
    return (PyObject *)so;
}

回答by GLHF

It's called intersection_update. return set s keeping only elements also found in t. As you see in this picture;

它被称为intersection_updatereturn set s 只保留在 t 中也找到的元素。正如你在这张照片中看到的那样;

enter image description here

在此处输入图片说明

You are re-building first set with intersection.

您正在重新构建具有交集的第一组。

回答by SomethingSomething

Copy the set by value instead of by refrerence

按值而不是按引用复制集合

tmp = set(s1)

(As s1is an instance of set)

(作为s1的一个实例set

回答by Rik Schoonbeek

It's not the &=operator that's causing the unexpected result, it's how Python works with storing objects in memory, and referincing them with variables (names).

&=导致意外结果的不是运算符,而是 Python 在内存中存储对象并使用变量(名称)引用它们的工作方式。

Everything in Python is an object, and it is stored somewhere in memory. Declaring a variable just tells Python that you are referencing a specific object that is stored at a specific location in memory, using the variable name as a reference to that object.

Python 中的一切都是一个对象,它存储在内存中的某个地方。声明一个变量只是告诉 Python 你正在引用一个存储在内存中特定位置的特定对象,使用变量名作为对该对象的引用。

You can get some information about the memory location of the object using the builtin id()function, example:

您可以使用内置id()函数获取有关对象内存位置的一些信息,例如:

s1 = {1,2,3}
s2 = {2,3,4}
tmp = s1
id(tmp)
1763330653544
id(s1)
1763330653544

Some information about builtin id()function:

关于内置id()函数的一些信息:

Return the “identity” of an object. This is an integer which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id() value.

CPython implementation detail: This is the address of the object in memory.

返回对象的“身份”。这是一个整数,保证在此对象的生命周期内是唯一且恒定的。生命周期不重叠的两个对象可能具有相同的 id() 值。

CPython 实现细节:这是对象在内存中的地址。

Link to Python docs in id() function

链接到 id() 函数中的 Python 文档

As you can see, by using the id()function, the object being referenced by the names tmpand s1is the same, since the integer value returned is the same.

如您所见,通过使用该id()函数,名称tmp和引用的对象s1是相同的,因为返回的整数值是相同的。

So, when you alter either one, the other changes as wel. Actually what I am saying in the last sentence isn't technically correct, since there is no 'either', just one set object in memory with two different references (tmpand s1).

所以,当你改变其中一个时,另一个也会随之改变。实际上我在最后一句中所说的在技术上是不正确的,因为没有“任一”,内存中只有一个具有两个不同引用(tmps1)的集合对象。

s1 = {3, 4, 5}
s2 = s1
s2.add(6)
s1
{3, 4, 5, 6}
id(s1)
1763330653320
id(s2)
1763330653320

It's not always this simple though, so if you want to understand this I recommend looking up Python memory management, and variable referencing.

然而,它并不总是那么简单,所以如果你想理解这一点,我建议你查看 Python 内存管理和变量引用。

Real Python seems do to a good job explaining object referencing (with names/variables), link to the page.

真正的 Python 似乎很好地解释了对象引用(带有名称/变量),链接到页面