35

I have a dictionary

lang = {'ar':'arabic', 'ur':'urdu','en':'english'}

What I want to do is to delete all the keys except one key. Suppose I want to save only en here. How can I do it ? (pythonic solution)
What I have tried:

In [18]: for k in lang:
   ....:     if k != 'en':
   ....:         del lang_name[k]
   ....

Which gave me the run time error:RuntimeError: dictionary changed size during iteration

dreftymac
  • 31,404
  • 26
  • 119
  • 182
NIlesh Sharma
  • 5,445
  • 6
  • 36
  • 53

4 Answers4

46

Why don't you just create a new one?

lang = {'en': lang['en']}

Edit: Benchmark between mine and jimifiki's solution:

$ python -m timeit "lang = {'ar':'arabic', 'ur':'urdu','en':'english'}; en_value = lang['en']; lang.clear(); lang['en'] = en_value"
1000000 loops, best of 3: 0.369 usec per loop

$ python -m timeit "lang = {'ar':'arabic', 'ur':'urdu','en':'english'}; lang = {'en': lang['en']}"
1000000 loops, best of 3: 0.319 usec per loop

Edit 2: jimifiki's pointed out in the comments that my solution keeps the original object unchanged.

Fabian
  • 4,160
  • 20
  • 32
  • 3
    Because he wants to modify the dictionary he access HERE as lang and elsewhere as something.attributeName. Maybe. – jimifiki Sep 12 '12 at 12:06
  • @jimifiki something.attributeName? – Fabian Sep 12 '12 at 12:10
  • let say he writes lang = someObject.attributeDict; lang = {'en':lang['en']}. Does someObject.attributeDict gets affected by these two lines? – jimifiki Sep 12 '12 at 12:13
  • @jimifiki nope, and the OP did not state that he wants to do something like that. – Fabian Sep 12 '12 at 12:17
  • Fabian, can you tell me something about timeit? is it already in python and how can i use it in .py file? – Marko Sep 12 '12 at 12:18
  • 1
    @Marko yep, it's built-in and you can use it from CLI and in Python files: http://docs.python.org/library/timeit.html – Fabian Sep 12 '12 at 12:18
  • "What I want to do is to delete all the keys except one key" means he wants to modify the object. You are just assigning the same name to another object. Probably (95%) he needs your solution. But he has to keep in mind that the original object remains unchanged... It's not a surprise that your answer runs faster (you avoid the clear()). – jimifiki Sep 12 '12 at 12:21
  • @jimifiki ok, I give you that. Let's see what he responds. Upvoted your answer. – Fabian Sep 12 '12 at 12:23
32

This is quite fast:

En_Value = lang['en']
lang.clear() 
lang['en'] = En_Value
jimifiki
  • 5,377
  • 2
  • 34
  • 60
9

Iterate over keys() instead:

for k in lang.keys():
    if k != 'en':
        del lang_name[k]

If you're using Python 3 I believe you need to use list(lang.keys()) instead.

thegrinner
  • 11,546
  • 5
  • 41
  • 64
6

pop() it via for loop like this

[s.pop(k) for k in list(s.keys()) if k != 'en']
nehem
  • 12,775
  • 6
  • 58
  • 84