Which is the fastest way of creating a copy of dictionary without specific (sub)keys?

195 views Asked by At

I need to know the fastest way of getting a copy of a dictionary without a specific key.

I have a dict like this:

users = {
    1: {'state': 'apple', 'menu_id': 123, 'args':['some data']},
    2: {'state': 'something', 'menu_id': 321},
    3: {'state': 'banana', 'menu_id': 666, 'args':['trash', 'temporary']}
}

I need to get a copy of users without 'args' key
I've solved this problem in three ways and there are my 3 solutions:

Solution 1:

s = users.copy()
for k,v in s.items(): 
    v.pop('args', None)

Solution 2:

s = {k: {'state': v['state'], 'menu_id':v['menu_id']} for k,v in users.items()}

Solution 3:

s = {k: {p: q for p,q in v.items() if p != 'args'} for k, v in users.items()}

Which solution is faster or are there any other faster ways to get the expected result?

2

There are 2 answers

0
Slam On BEST ANSWER
  • First approach is not even viable — it's destructive for original data. You're making copy, not deepcopy, which means that for k,v in obj.items(): v.pop('args', None) will mutate sub-dicts in original structure.
  • 2nd approach is (in my opinion) semantically wrong — you're not "creating without specific key", you're creating new "based on specific key". This is different at all, and this is not a technical question, this is question for business logic.
  • 3rd one is the only one that matches for what you're trying to achieve, and this is pretty idiomatic way to do this in python.

Even if performance should not bother you until you'll face performance problems, but anyway, considering 3rd one as base:

  • destructive approach is fastest
  • 1st approach with deepcopy is magnitude slower than 3rd one
  • 2nd is ~2 times faster than 3rd
0
nejdetckenobi On

First of all, I wouldn't use s2 in anywhere. Because it's hard to read. Python code should be readable.

And when it comes to s1 and s, they are kinda different. copy function uses the same object reference with your original object's values. So after you applied solution s, if you make changes in dictionaries in users, you'll see your changes in s. But if you use s1, because of the new objects are created, the changes will not occur in s1.