Python dict, duplicatede keys or None accoure

Have a class in python where I have a dict containing neighbors, and a list pri_list containing 21 instens of the class, but if I iterate over the neighbor, duplicatede keys or None accoure.
have asked the same problem on stackoverflow in the tread http://stackoverflow.com/questions/28325258/python-dict-duplicatede-keys-or-none-accoure but hougth the rhino communiti maby have a better inside into this

print type(self.neighbors)
print str(self.id) + " " + str(self.neighbors)
print ""
for n in self.neighbors:
    print str(pri_list[n].id) + " " + str(pri_list[n].neighbors)
    pri_list[n].neighbors.update({self.id:self.neighbors[n]})
    print str(pri_list[n].id) + " " + str(pri_list[n].neighbors)

resulting in

<type 'dict'>
21 {22: 34.348765355132869, 23: 0, 19: 0.049076419727497315, 20: 36.087031068160286}

22 {21: 34.348765355132869, 23: 34.602568871995345, 8: 0.2351466696454737, 17: 0, 20: 0}
22 {21: 34.348765355132869, 23: 34.602568871995345, 8: 0.2351466696454737, 17: 0, 20: 0}
23 {21: 0, 22: 34.602568871995345, 8: 26.643673903936367, 17: 36.80385613689073}
23 {21: 0, 21: 0, 22: 34.602568871995345, 8: 26.643673903936367, 17: 36.80385613689073}
19 {21: 0.049076419727497315, 14: 0, 18: 41.407044987390677, 20: 39.517515427920443}
19 {21: 0.049076419727497315, 14: 0, 18: 41.407044987390677, 20: 39.517515427920443}
20 {21: 36.087031068160286, 22: 0, 18: 0.58414114578772669, 19: 39.517515427920443}
20 {21: 36.087031068160286, 22: 0, 18: 0.58414114578772669, 19: 39.517515427920443}

Observe how the key 21 accour twice in the id=23 dict after doing a update. have tried

pri_list[n].neighbors[self.id] = self.neighbors[n]

Giving the same result.

Have tried it on two diffrent machines which gave the same result.

Have make a test exmaple where I copyed the data from the dict over as.

class A:
    neighbors = {}
    id = 0

    def __init__(self,id, neighbors):
        self.id = id
        self.neighbors = neighbors.copy()

if __name__ == "__main__":
    pri_list = [A(i, {})for i in range(0, 19)]

    pri_list.append(A(19, {21: 0.049076419727497315, 14: 0, 18: 41.407044987390677, 20: 39.517515427920443}))
    pri_list.append(A(20, {21: 36.087031068160286, 22: 0, 18: 0.58414114578772669, 19: 39.517515427920443}))
    pri_list.append(A(21, {22: 34.348765355132869, 23: 0, 19: 0.049076419727497315, 20: 36.087031068160286}))
    pri_list.append(A(22, {21: 34.348765355132869, 23: 34.602568871995345, 8: 0.2351466696454737, 17: 0, 20: 0}))
    pri_list.append(A(23, {21: 0, 22: 34.602568871995345, 8: 26.643673903936367, 17: 36.80385613689073}))

    print type(pri_list[21].neighbors)
    print str(pri_list[21].id) + " " + str(pri_list[21].neighbors)
    print ""

    for n in pri_list[21].neighbors:
        print str(pri_list[n].id) + " " + str(pri_list[n].neighbors)
        pri_list[n].neighbors.update({pri_list[21].id:pri_list[21].neighbors[n]})
        print str(pri_list[n].id) + " " + str(pri_list[n].neighbors)

This gave the expected result

<type 'dict'>
21 {22: 34.348765355132869, 23: 0, 19: 0.049076419727497315, 20:     36.087031068160286}

22 {8: 0.2351466696454737, 17: 0, 20: 0, 21: 34.348765355132869, 23: 34.602568871995345}
22 {8: 0.2351466696454737, 17: 0, 20: 0, 21: 34.348765355132869, 23: 34.602568871995345}
23 {21: 0, 22: 34.602568871995345, 8: 26.643673903936367, 17: 36.80385613689073}
23 {21: 0, 22: 34.602568871995345, 8: 26.643673903936367, 17: 36.80385613689073}
19 {21: 0.049076419727497315, 14: 0, 18: 41.407044987390677, 20: 39.517515427920443}
19 {21: 0.049076419727497315, 14: 0, 18: 41.407044987390677, 20: 39.517515427920443}
20 {21: 36.087031068160286, 22: 0, 18: 0.58414114578772669, 19: 39.517515427920443}
20 {21: 36.087031068160286, 22: 0, 18: 0.58414114578772669, 19: 39.517515427920443}

Observe how the key 21 accour only ones in the id=23 dict after doing a update. and the arangment of the dict is also diffrent.

Having a hard time even grasping how multiple keys can accour in the same dict, acccourding to https://docs.python.org/2/library/stdtypes.html#dict this should not be possiable

I don’t see anything amiss here. None of your dictionaries have multiple keys.

Dictionaries are non-ordered collections, so you can’t for instance expect the dictionary yields elements in the order you added them, nor can you assume ascending or descending key order. For that you’ll have to do some extra work yourself.

Slightly adding more info to your output will clarify what you get:

class A:
    neighbors = {}
    id = 0

    def __init__(self,id, neighbors):
        self.id = id
        self.neighbors = neighbors.copy()

if __name__ == "__main__":
    pri_list = [A(i, {})for i in range(0, 19)]

    pri_list.append(A(19, {21: 0.049076419727497315, 14: 0, 18: 41.407044987390677, 20: 39.517515427920443}))
    pri_list.append(A(20, {21: 36.087031068160286, 22: 0, 18: 0.58414114578772669, 19: 39.517515427920443}))
    pri_list.append(A(21, {22: 34.348765355132869, 23: 0, 19: 0.049076419727497315, 20: 36.087031068160286}))
    pri_list.append(A(22, {21: 34.348765355132869, 23: 34.602568871995345, 8: 0.2351466696454737, 17: 0, 20: 0}))
    pri_list.append(A(23, {21: 0, 22: 34.602568871995345, 8: 26.643673903936367, 17: 36.80385613689073}))

    print "###############"
    print type(pri_list[21].neighbors)
    print str(pri_list[21].id) + " " + str(pri_list[21].neighbors)


    for n in pri_list[21].neighbors:
        print "--------------"
        print str(pri_list[n].id) + " " + str(pri_list[n].neighbors)
        d = {pri_list[21].id:pri_list[21].neighbors[n]}
        print "new dictionary to use in update:" + str(d)
        pri_list[n].neighbors.update(d)
        print "===>" + str(pri_list[n].id) + " " + str(pri_list[n].neighbors)

As you can see from the output, all dictionaries are correct

###############
<class 'dict'>
21 {19: 0.049076419727497315, 20: 36.087031068160286, 22: 34.34876535513287, 23: 0}
--------------
19 {18: 41.40704498739068, 20: 39.51751542792044, 21: 0.049076419727497315, 14: 0}
new dictionary to use in update: {21: 0.049076419727497315}
===> 19 {18: 41.40704498739068, 20: 39.51751542792044, 21: 0.049076419727497315, 14: 0}
--------------
20 {18: 0.5841411457877267, 19: 39.51751542792044, 21: 36.087031068160286, 22: 0}
new dictionary to use in update: {21: 36.087031068160286}
===> 20 {18: 0.5841411457877267, 19: 39.51751542792044, 21: 36.087031068160286, 22: 0}
--------------
22 {8: 0.2351466696454737, 17: 0, 20: 0, 21: 34.34876535513287, 23: 34.602568871995345}
new dictionary to use in update: {21: 34.34876535513287}
===> 22 {17: 0, 20: 0, 21: 34.34876535513287, 23: 34.602568871995345, 8: 0.2351466696454737}
--------------
23 {8: 26.643673903936367, 17: 36.80385613689073, 21: 0, 22: 34.602568871995345}
new dictionary to use in update: {21: 0}
===> 23 {8: 26.643673903936367, 17: 36.80385613689073, 21: 0, 22: 34.602568871995345}

I’m not sure where you’re seeing None or double keys. Of course it’d help greatly if I knew what you’re trying to achieve.

You missunderstod the problem, in the test case everything work find (which is what is surprise me ), as show in the last part of the question, but if I do that same in a larger program (the start of the question) then dublicated of the key 21 apperes

23 {21: 0, 21: 0, 22: 34.602568871995345, 8: 26.643673903936367, 17: 36.80385613689073}

The only explanation I can come up with is that dict is not threat safe in the rhino version, but it should be. The large code is many 1000 lines of code, but have isolated the problem to this few lines of code.

The None is not pressent in this qestion, but I can produce that aswell.

But thanks for testing my test example, realy hope to get to the botton of this problem, since it is breaking so much code :smile: