Home > Software design >  Why do I get duplicate keys in dictionaries and in lists in Python?
Why do I get duplicate keys in dictionaries and in lists in Python?

Time:06-09

My problem is, I sometimes get duplicate keys in dictionaries or lists (checking if the item is there beforehand). I couldn't manage to reproduce it with any consistency.

Currently I am saving a list of users accessing my telegram bot in some way like:

async def myfunction()
 ..........
     users={}
     if os.access("userlist.json", os.R_OK):
         with open ('userlist.json') as f:
             users=json.load(f)
     currentuser=[str(update.message.from_user.id),update.message.from_user.username,update.message.from_user.first_name,update.message.from_user.last_name,False,1]
     if currentuser[0] in users:
         currentuser[5] =users[currentuser[0]][5] #counting how many messages the user sent to the bot
     users[currentuser[0]]=currentuser
     with open ('userlist.json','w') as f:
         json.dump(users,f)
........

Here's in example of a json dump of a dictionary from the server:

{"1033556742": [1033556742, "CatchingStars", "Starcatcher", null, false, 1], "1033556742": [1033556742, "CatchingStars", "Starcatcher", null, false, 1]}

Also I have a similar patch of code where I add items to a list in a similar way: I load a list from json, I check if the item is in the list with:

if item in list: print ('ok')
else: 
     list.append(item)
     with ('mylist.json','w') as f:
           json.dump(list,f)

and I get duplicate items there too, sporadically.

CodePudding user response:

I can explain your duplicate keys. It's a quirk of the json module.

The issue is that JSON does not support numeric keys. Keys must always be strings. You are loading your JSON, which has a string key, then you are adding another entry with the same value as an integer. Python allows that, as two separate keys, but the JSON module converts it to a string. Watch:

Python 3.8.10 (default, Mar 15 2022, 12:22:08) 
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import json
>>> x = {123:'abc', "123":'abc'}
>>> x
{123: 'abc', '123': 'abc'}
>>> json.dumps(x)
'{"123": "abc", "123": "abc"}'
>>> 
  • Related