views:

249

answers:

4

Hey!

I have a dictionary, lets call it myDict, in Python that contains a set of similar dictionaries which all have the entry "turned_on : True" or "turned_on : False". I want to remove all the entries in myDict that are off, e.g. where "turned_on : False". In Ruby I would do something like this:

myDict.delete_if { |id,dict| not dict[:turned_on] }

How should I do this in Python?

+5  A: 

Straight-forward way:

def delete_if_not(predicate_key, some_dict):
    for key, subdict in some_dict.items():
        if not subdict.get(predicate_key, True):
            del some_dict[key]

Testing:

mydict = {
        'test1': {
                'turned_on': True,
                'other_data': 'foo',
            },
        'test2': {
            'turned_on': False,
            'other_data': 'bar',
            },
        }
delete_if_not('turned_on', mydict)
print mydict

The other answers on this page so far create another dict. They don't delete the keys in your actual dict.

nosklo
it seems to be guarantee that all `subdicts` have a `'turned_on'` key.
SilentGhost
adding the check costed me nothing and the function is now more generic (can be used in any dict of dicts).
nosklo
+2  A: 

It's not clear what you want, but my guess is:

myDict = {i: j for i, j in myDict.items() if j['turned_on']}

or for older version of python:

myDict = dict((i, j) for i, j in myDict.iteritems() if j['turned_on'])
SilentGhost
Is this a Python3.0 thing? You can't do 'dict comprehensions' in 2.5, certainly.
Daniel Roseman
Python 3.0 is a stable version of python. I've added py2k version for those downvoters who cannot expand this primitive syntax.
SilentGhost
@SilentGhost: While I wouldn't downvote you, python 3 is not widely used yet, because of the lack of useful 3rd party libraries to do simple things, like connecting to some RDBMS, thus providing a py3-only answer is frowned upon for a while.
nosklo
@nosklo: my dismay is aimed at those who cannot see past such a transparent syntax. py3k was out for almost 9 months out and is a stable version of python, providing only 2k version should be frowned upon too, don't you think. At this rate py3k will be adopted at the end of the century.
SilentGhost
@SilentGhost: well, the python 2.x version works on python 3 just fine, so it is not frowned upon. Even if it did, it is still reasonable to assume everyone is using 2.x unless explicity noted, since 3.x is still hard to use for serious stuff.
nosklo
http://python.org/ have lots of examples on that. If you click on DOCUMENTATION -> CURRENT DOCS (without specifying any version) it still redirects you to 2.6.2 docs. If you click on DOWNLOAD, there's a notice near the top of the page that says: *If you don't know which version to use, start with Python 2.6.2; more existing third party software is compatible with Python 2 than Python 3 right now.*
nosklo
as well as: The **current production** versions are Python 2.6.2 and Python 3.1.1.Start with one of these versions for learning Python or if you want the most stability; they're **both considered stable production releases**.Emphasis mine
SilentGhost
yeah, you just made my point. Python 2.x is listed first. And just after that sentence comes the one I said on my previous comment. python.org clearly favors 2.x, that's plain clear for anyone.
nosklo
+5  A: 

You mean like this?

myDict = {"id1" : {"turned_on": True}, "id2" : {"turned_on": False}}
result = dict((a, b) for a, b in myDict.items() if b["turned_on"])

output:

{'id1': {'turned_on': True}}
Nadia Alramli
`turned_off` was just typo in the question.
SilentGhost
Thanks I corrected it
Nadia Alramli
+1  A: 
d = { 'id1':{'turned_on':True}, 'id2':{'turned_on':False}}
dict((i,j) for i, j in d.items() if not j['turned_on'])
Daniel Roseman