Can someone explain this bizarre mistake repeating itself over the multitude?

I had a loop of shape for thing in a_set:. It did not work correctly, because, occasionally and inconsistently, he pulled the same thing out of the set twice. (This does not cause the program to crash. It just gets the wrong answer.) I was not able to determine anything deterministic about the wrong behavior; but my attempts to debug this made it very clear that weirdness happened sometimes. In those cases when I observed this most closely, there were 3 elements in the set (before and after), and the cycle was performed 4 times, once with the repetition of one of the objects. Elements were references to objects of class I that were created (treated more like a C structure). The bad behavior went away when I changed the for statement to for thing in list(a_set):.

I have a complete loss to explain the wrong behavior. I am very sure that nothing in the body of the loop can cause what it does to happen twice or change the value of the variable thing. I am absolutely sure that what is happening in the cycle cannot affect the composition of the set. Moreover, even if it were possible, I believe that this will lead to RuntimeError. I completely disagree with the hypotheses about what might be causing this. The lack of repeatability with the same code is sequentially mysterious. My attempts to recreate the symptom in a simpler scenario failed. However, I would feel stupid about leaving a challengelist()there to solve a problem that I cannot explain. Any other suggestion would be welcome. I need ideas on what things I should try to eliminate when debugging.

Update: I think this question was incorrectly postponed based on the claim that it is not relevant to the topic. Lack of reproducibility was a problem in this case, and I suspected that there was some nuance in the language that I was missing. Indeed, this is true, and MSeifert's answer put me on what caused it. However, it was not as simple as he suggested, as I note in the commentary on his answer.

, , . . , . ( , , "mutable" , Python.) , , . , Python .

0
1

, list(a_set), , . a RuntimeError, , , :

a = {1,2,3}
for item in a:
    print(item)
    a.add(item+3)  # add one item
    a.remove(item) # remove one item

1 31 ( , ), , set 3 .

, list, ( ) , :

a = {1,2,3}
for item in list(a):
    print(item)
    a.add(item+3)
    a.remove(item)

print(a)

:

1
2
3
set([4, 5, 6])   # totally changed!

, , , , , , , ( set). set dict, , __hash__ __eq__.

, "" :

class Fun(object):
    def __init__(self, value):
        self.value = value

    def __repr__(self):
        return '{self.__class__.__name__}({self.value})'.format(self=self)

    def __eq__(self, other):
        return self.value == other.value

a = {Fun(1),Fun(2),Fun(3)}
for item in a:
    print(item)
    a.add(Fun(item.value+3))
    a.remove(item)

"" ( , , id , , ) Fun , .

+6

Source: https://habr.com/ru/post/1684696/


All Articles