473,591 Members | 2,871 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Delete items in nested dictionary based on value.

I've got a problem that I can't seem to get my head around and hoped
somebody might help me out a bit:

I've got a dictionary, A, that is arbitarily large and may contains
ints, None and more dictionaries which themselves may contain ints,
None and more dictionaries. Each of the sub-dictionaries is also
arbitrarily large. When pretty printing A, in the context I'm using A
for, it's rather helpful to remove all key:value pairs where value is
None. So I'd like to be able to define a function dict_sweep to recurse
through A and del all the keys with None as a value.

I feel like the solution is right on the tip of my tounge, so to speak,
but I just can't quite get it. Anyway, here's the best I've come up
with:

def dict_sweep(dict ionary, key_value):
"""Sweep through dictionary, deleting any key:value where
value is None.

"""
# Find key at position key_value.
key = dictionary.keys ()[key_value]

# If the key value is a dictionary we want to move into it.
# Therefore we call rec_rem on dictionary[key] with a
# key_value of 0
if type(dictionary[key]) is type({}):
dict_sweep(dict ionary[key], 0)

# If the value isn't a dictionary we care only that it's not None.
# If it is None we nuke it and call rec_rem on the current
# dictionary with key_value incrimented by one.
elif dictionary[key] is None:
del dictionary[key]
dict_sweep(dict ionary, key_value+1)

# If the value isn't a dictionary and the value isn't None then
# we still want to walk through to the next value in the
# dictionary, so call rec_rem with key_value+1
else:
dict_sweep(dict ionary, key_value+1)

Assuming dict_sweep worked perfectly it would take input like this:

A_in = {1: {2: 2, 3: {1: None, 2: 2}}, 2: 2, 3: None}

B_in = {1: {1: {1: None, 2: {1: None}}, 2: 2, 3: None}

and output this:

A_out = {1: {2: 2, 3: {2: 2}}, 2: 2}

B_out = {2:2}

This dict_sweep above obviously doesn't work and I'm rather afraid of
hitting python's recursion limit. Does anyone see a way to modify
dict_sweep in it's current state to perform dictionary sweeps like
this? What about a non-recursive implementation of dict_sweep?

Sep 13 '06 #1
8 13303
My first try, not much tested:

def clean(d):
for key,val in d.items():
if isinstance(val, dict):
val = clean(val)
if not val:
del d[key]
return d

a = {1: {2: 2, 3: {1: None, 2: 2}}, 2: 2, 3: None}
print clean(a) # Out: {1: {2: 2, 3: {2: 2}}, 2: 2}
b = {1: {1: {1: None, 2: {1: None}}}, 2: 2, 3: None}
print clean(b) # Out: {2: 2}

Recursivity overflow problem: you can increase the recursivity limit,
of if you think you need it after some tests on your real data, then
you can use a stack (a python list, using append and pop methods) to
simulate recursivity. You probably don't have 300+ levels of nesting.

Bye,
bearophile

Sep 13 '06 #2
Better:

def clean(d):
for key,val in d.items():
if isinstance(val, dict):
val = clean(val)
if val is None or val == {}:
del d[key]
return d

a = {1: {2: 2, 3: {1: None, 2: 2}}, 2: 2, 3: None}
print clean(a) # Out: {1: {2: 2, 3: {2: 2}}, 2: 2}
b = {1: {1: {1: None, 2: {1: None}}}, 2: 2, 3: None}
print clean(b) # Out: {2: 2}
c = {1: {1: {1: None, 2: {1: None}}}, 2: 2, 3: 0}
print clean(c) # Out: {2: 2, 3: 0}

Sep 13 '06 #3
Brian L. Troutwine wrote:
I've got a problem that I can't seem to get my head around and hoped
somebody might help me out a bit:

I've got a dictionary, A, that is arbitarily large and may contains
ints, None and more dictionaries which themselves may contain ints,
None and more dictionaries. Each of the sub-dictionaries is also
arbitrarily large. When pretty printing A, in the context I'm using A
for, it's rather helpful to remove all key:value pairs where value is
None. So I'd like to be able to define a function dict_sweep to recurse
through A and del all the keys with None as a value.

I feel like the solution is right on the tip of my tounge, so to speak,
but I just can't quite get it. Anyway, here's the best I've come up
with:
How about this:

def dict_sweep(dict ionary):
for k, v in dictionary.item s():
if v is None:
del dictionary[k]
if type(v) == type({}):
dict_sweep(v)
#if len(v) == 0:
# del dictionary[k]
A_in = {1: {2: 2, 3: {1: None, 2: 2}}, 2: 2, 3: None}

B_in = {1: {1: {1: None, 2: {1: None}}, 2: 2, 3: None}}

dict_sweep(A_in )
dict_sweep(B_in )
print A_in
print B_in
>>{1: {2: 2, 3: {2: 2}}, 2: 2}
{1: {2: 2}}

It doesn't produce the output you expect for B_in, but your brackets didn't
match and I'm not sure where the extra close should be. Also, I suspect
you're wanting to delete empty dictionaries but I don't see that mentioned
in the text. If that is so, include the two commented statements.
--
Dale Strickland-Clark
Riverhall Systems - www.riverhall.co.uk

Sep 13 '06 #4

be************@ lycos.com wrote:
Better:

def clean(d):
for key,val in d.items():
if isinstance(val, dict):
val = clean(val)
if val is None or val == {}:
del d[key]
return d
Can you delete values from a dictionary whilst iterating over its items
?

Fuzzyman
http://www.voidspace.org.uk/python/index.shtml
>
a = {1: {2: 2, 3: {1: None, 2: 2}}, 2: 2, 3: None}
print clean(a) # Out: {1: {2: 2, 3: {2: 2}}, 2: 2}
b = {1: {1: {1: None, 2: {1: None}}}, 2: 2, 3: None}
print clean(b) # Out: {2: 2}
c = {1: {1: {1: None, 2: {1: None}}}, 2: 2, 3: 0}
print clean(c) # Out: {2: 2, 3: 0}
Sep 13 '06 #5
Fuzzyman:
Can you delete values from a dictionary whilst iterating over its items ?
Try the code, it works. I am not iterating on the dict, I am not using
dict.iteritems( ), that produces a lazy iterable, I am using
dict.items() that produces a list of (key,value) pairs. And I am not
removing elements from that list :-)

Hugs,
bearophile

Sep 13 '06 #6
>
Assuming dict_sweep worked perfectly it would take input like this:

A_in = {1: {2: 2, 3: {1: None, 2: 2}}, 2: 2, 3: None}

B_in = {1: {1: {1: None, 2: {1: None}}, 2: 2, 3: None}

and output this:

A_out = {1: {2: 2, 3: {2: 2}}, 2: 2}

B_out = {2:2}

This dict_sweep above obviously doesn't work and I'm rather afraid of
hitting python's recursion limit. Does anyone see a way to modify
dict_sweep in it's current state to perform dictionary sweeps like
this? What about a non-recursive implementation of dict_sweep?
How about this:

A_in = {1: {2: 2, 3: {1: None, 2: 2}}, 2: 2, 3: None}

def dict_sweep(dict in):

for key in dictin.keys():
if dictin.get(key) == None:
del dictin[key]
elif type(dictin[key]) is dict:
dictin[key] = dict_sweep(dict in[key])
return dictin

A_out = dict_sweep(A_in )
print A_out


Running the above returns:

{1: {2: 2, 3: {2: 2}}, 2: 2}

Regards,

John


--
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.

Sep 14 '06 #7
Would it not be easier to modify the pretty-printer to ignore such
entries rather than have to make a duplicate (I presume you have reason
to need the original dictionary unchanged) dictionary and then delete
entries that match your "ignore" criteria?
Good question. The data I'm handling relates to books: their ISBN,
pricing information, weight, statistical data for each page, citations
in other books to certain pages, those books statistical data, so on
and so forth. It's too much data, really, but this is what I'm tasked
with handling.

Currently I'm just pretty printing the data, but I'm really cheating
right now. The tool I'm writing is supposed to just collect the data,
strip out all the extranious data based on filters defined at the start
of the collection process and then output all that data to stdout,
where it will be caught by a tool to properly format and display it.

Yesterday morning I got into work, went into deep hack mode, wrote the
entire tool and at the end of the day could not, for the life of me,
figure out the recursion I needed. I suppose I'd spent myself. Who
knows?

Anyway, you are right in that if I did indeed need the original
dictionary unchanged it would be much, much easier to modify the
pretty-printer.

Dennis Lee Bieber wrote:
On 13 Sep 2006 16:08:37 -0700, "Brian L. Troutwine"
<go************ *@gmail.comdecl aimed the following in comp.lang.pytho n:
arbitrarily large. When pretty printing A, in the context I'm using A
for, it's rather helpful to remove all key:value pairs where value is
None. So I'd like to be able to define a function dict_sweep to recurse
through A and del all the keys with None as a value.

I feel like the solution is right on the tip of my tounge, so to speak,
but I just can't quite get it. Anyway, here's the best I've come up
with:
Would it not be easier to modify the pretty-printer to ignore such
entries rather than have to make a duplicate (I presume you have reason
to need the original dictionary unchanged) dictionary and then delete
entries that match your "ignore" criteria?
--
Wulfraed Dennis Lee Bieber KD6MOG
wl*****@ix.netc om.com wu******@bestia ria.com
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: we******@bestia ria.com)
HTTP://www.bestiaria.com/
Sep 14 '06 #8
This is a general reply to all.

Thanks for all the suggestions. I hadn't really thought about filtering
empty dictionaries because the data I'm processing won't have them, but
it does make for a much nicer, more general filter. I did end up using
bearophileH's code, but that's mostly because he got there first. Each
solution functioned as advertised.

Again, thanks for all the help.

Sep 14 '06 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
13055
by: Charlotte Henkle | last post by:
Hello; I'm pondering how to count the number of times an item appears in total in a nested list. For example: myList=,,] I'd like to know that a appeared three times, and b appeared twice, and the rest appeard only once.
12
1894
by: Donnal Walter | last post by:
The following method is defined in one of my classes: def setup(self, items={}): """perform setup based on a dictionary of items""" if 'something' in items: value = items # now do something with value if 'another' in items: value = items # do something else with value
6
559
by: B0nj | last post by:
I've got a class in which I want to implement a property that operates like an indexer, for the various colors associated with the class. For instance, I want to be able to do 'set' operations like MyClass.MyColors = Color.Green or, a 'get', such as Color forecolor = MyClass.MyColors; I want to use an indexer so I can take parameters, such as the color type (e.g. "Foreground", "Background" etc.). With a single member function I couldn't...
2
2245
by: Antoine | last post by:
I would like to construct my own list of items in a grid/ table/ item list layout but I have a problem. I want to add a sort of index row based on time, such as there might be blank values. Sure the data list I have at the moment is in order, but I would like to have each interval possible, and instead of repeating the row index (the time value) I would like to list it once and then list the items within it (the items associated with...
3
2046
by: Jake Emerson | last post by:
I'm attempting to build a process that helps me to evaluate the performance of weather stations. The script below operates on an MS Access database, brings back some data, and then loops through to pull out statistics. One such stat is the frequency of reports from the stations ('char_freq'). I have a collection of methods that operate on the data to return the 'char_freq' and this works great. However, when the process goes to insert the...
1
5464
by: georgehernando | last post by:
I am looking for an efficient way to delete the elements of a Python dictionary based on an evaluation of the element's value. Delete all elements with value bigger than x. Thanks
12
1449
by: Rich Shepard | last post by:
I want to code what would be nested "for" loops in C, but I don't know the most elegant way of doing the same thing in python. So I need to learn how from you folks. Here's what I need to do: build a database table of 180 rows. Each row contains 31 columns: the first is an automatically incremented integer as the primary key; the next two fields can each contain one of three strings held in dictionaries, the last 28 fields are random...
16
1621
by: IamIan | last post by:
Hello, I'm writing a simple FTP log parser that sums file sizes as it runs. I have a yearTotals dictionary with year keys and the monthTotals dictionary as its values. The monthTotals dictionary has month keys and file size values. The script works except the results are written for all years, rather than just one year. I'm thinking there's an error in the way I set my dictionaries up or reference them... import glob, traceback
0
2066
by: Gary Herron | last post by:
Dan Upton wrote: Yes. Create a list of keys, and loop through it: pids = procs_dict.keys() for pid in pids: if procs_dict.poll() != None # do the counter updates del procs_dict Then the diction delete operation won't trip up the loop and its
0
7934
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
7870
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8236
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8225
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6639
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
5732
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5400
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
3891
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2378
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.