Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > splitting one dictionary into two

Reply
Thread Tools

splitting one dictionary into two

 
 
jsaul
Guest
Posts: n/a
 
      04-01-2004
Hello all,

I have to split a dict into two dicts. Depending on their values,
the items shall remain in the original dict or be moved to another
one and at the same time be removed from the original dict.

OK, this is how I do it right now:

dict1 = { "a":1, "b":3, "c":5, "d":4, "e":2 }
dict2 = {}
klist = []

for key in dict1:
if dict1[key] > 3: # some criterion
dict2[key] = dict1[key]
klist.append(key)

for key in klist:
del dict1[key]

print dict1
print dict2

That means that I store the keys of the items to be removed from
the original dict in a list (klist) and subsequently remove the
items using these keys.

Is there an "even more pythonic" way?

Cheers, jsaul
 
Reply With Quote
 
 
 
 
Terry Reedy
Guest
Posts: n/a
 
      04-01-2004

"jsaul" <use_reply-> wrote in message
news:...
> Hello all,
>
> I have to split a dict into two dicts. Depending on their values,
> the items shall remain in the original dict or be moved to another
> one and at the same time be removed from the original dict.
>
> OK, this is how I do it right now:
>
> dict1 = { "a":1, "b":3, "c":5, "d":4, "e":2 }
> dict2 = {}
> klist = []
>
> for key in dict1:
> if dict1[key] > 3: # some criterion
> dict2[key] = dict1[key]
> klist.append(key)
>
> for key in klist:
> del dict1[key]
>
> print dict1
> print dict2
>
> That means that I store the keys of the items to be removed from
> the original dict in a list (klist) and subsequently remove the
> items using these keys.
>
> Is there an "even more pythonic" way?


Delete klist stuff and do deletion with

for key in dict2: del dict1[key]

tjr




 
Reply With Quote
 
 
 
 
wes weston
Guest
Posts: n/a
 
      04-01-2004
jsaul wrote:
> Hello all,
>
> I have to split a dict into two dicts. Depending on their values,
> the items shall remain in the original dict or be moved to another
> one and at the same time be removed from the original dict.
>
> OK, this is how I do it right now:
>
> dict1 = { "a":1, "b":3, "c":5, "d":4, "e":2 }
> dict2 = {}
> klist = []
>
> for key in dict1:
> if dict1[key] > 3: # some criterion
> dict2[key] = dict1[key]
> klist.append(key)
>
> for key in klist:
> del dict1[key]
>
> print dict1
> print dict2
>
> That means that I store the keys of the items to be removed from
> the original dict in a list (klist) and subsequently remove the
> items using these keys.
>
> Is there an "even more pythonic" way?
>
> Cheers, jsaul


jsaul,
I'll have a hack with small code. Nice that you can
iterate while removing.
wes


dict1 = { "a":1, "b":3, "c":5, "d":4, "e":2 }
dict2 = {}

print dict1

for key,val in dict1.items():
if val > 3: # some criterion
dict2[key] = val
del dict1[key]

print dict1
print dict2

 
Reply With Quote
 
Peter Otten
Guest
Posts: n/a
 
      04-01-2004
jsaul wrote:

> I have to split a dict into two dicts. Depending on their values,
> the items shall remain in the original dict or be moved to another
> one and at the same time be removed from the original dict.
>
> OK, this is how I do it right now:
>
> dict1 = { "a":1, "b":3, "c":5, "d":4, "e":2 }
> dict2 = {}
> klist = []
>
> for key in dict1:
> if dict1[key] > 3: # some criterion
> dict2[key] = dict1[key]
> klist.append(key)
>
> for key in klist:
> del dict1[key]
>
> print dict1
> print dict2
>
> That means that I store the keys of the items to be removed from
> the original dict in a list (klist) and subsequently remove the
> items using these keys.
>
> Is there an "even more pythonic" way?


Only a minor change to do away with the temporary list:

for key in dict1:
if dict1[key] > 3: # some criterion
dict2[key] = dict1[key]

for key in dict2:
del dict1[key]

Peter

 
Reply With Quote
 
Larry Bates
Guest
Posts: n/a
 
      04-01-2004
There a quite a few different ways to do this, but
I might suggest something like:

dict1={"a":1, "b":3, "c":5, "d":4, "e":2}
dict2={}
dict3={}
[dict2.setdefault(k,v) for k,v in dict1.items() if v > 3]
[dict3.setdefault(k,v) for k,v in dict1.items() if not v > 3]
dict1=dict3.copy()

Very "Pythonic" but is 2 times slower than your original code.

Another suggestion is:

dict1 = { "a":1, "b":3, "c":5, "d":4, "e":2 }
dict2 = {}

keys=dict1.keys()
for key in keys:
if dict1[key] > 3: # some criterion
dict2[key] = dict1[key]
del dict1[key]

This is a "little" faster (100000 iterations of your method
time=1.13 seconds, my method=0.94 seconds and I find easier
to read (eliminates the unneeded klist variable and second
loop).

Larry Bates
Syscon, Inc.

"jsaul" <use_reply-> wrote in message
news:...
> Hello all,
>
> I have to split a dict into two dicts. Depending on their values,
> the items shall remain in the original dict or be moved to another
> one and at the same time be removed from the original dict.
>
> OK, this is how I do it right now:
>
> dict1 = { "a":1, "b":3, "c":5, "d":4, "e":2 }
> dict2 = {}
> klist = []
>
> for key in dict1:
> if dict1[key] > 3: # some criterion
> dict2[key] = dict1[key]
> klist.append(key)
>
> for key in klist:
> del dict1[key]
>
> print dict1
> print dict2
>
> That means that I store the keys of the items to be removed from
> the original dict in a list (klist) and subsequently remove the
> items using these keys.
>
> Is there an "even more pythonic" way?
>
> Cheers, jsaul



 
Reply With Quote
 
jsaul
Guest
Posts: n/a
 
      04-01-2004
* Peter Otten [2004-04-01 18:46]:
> jsaul wrote:
>
> > dict1 = { "a":1, "b":3, "c":5, "d":4, "e":2 }
> > dict2 = {}
> > klist = []
> >
> > for key in dict1:
> > if dict1[key] > 3: # some criterion
> > dict2[key] = dict1[key]
> > klist.append(key)
> >
> > for key in klist:
> > del dict1[key]
> >
> > print dict1
> > print dict2

>
> Only a minor change to do away with the temporary list:
>
> for key in dict1:
> if dict1[key] > 3: # some criterion
> dict2[key] = dict1[key]
>
> for key in dict2:
> del dict1[key]


Hi Peter and others who responded so quickly,

I notice now that I forgot to mention an important condition,
namely that in real life dict2 is already existing and may have
become huge. That's the reason why I need to somewhere save only
those items which I most recently removed from the 1st dict, as
I want to avoid iterating over the while dict2. In real life,
dict1 contains pending jobs which, after they are done, are moved
to a second dict for post processing.

Sorry for the confusion.

I think the most "pythonic" candidate is actually the version
suggested by Larry, namely

dict1 = { "a":1, "b":3, "c":5, "d":4, "e":2 }
dict2 = {} # in real life, dict2 already exists

for key in dict1.keys():
if dict1[key] > 3:
dict2[key] = dict1.pop(key)

print dict1
print dict2

Cheers, jsaul
 
Reply With Quote
 
wes weston
Guest
Posts: n/a
 
      04-01-2004
jsaul wrote:
> I notice now that I forgot to mention an important condition,
> namely that in real life dict2 is already existing and may have
> become huge.


jsaul,
How huge is huge?
wes

 
Reply With Quote
 
Peter Abel
Guest
Posts: n/a
 
      04-02-2004
jsaul <use_reply-> wrote in message news:<>...
> Hello all,
>
> I have to split a dict into two dicts. Depending on their values,
> the items shall remain in the original dict or be moved to another
> one and at the same time be removed from the original dict.
>
> OK, this is how I do it right now:
>
> dict1 = { "a":1, "b":3, "c":5, "d":4, "e":2 }
> dict2 = {}
> klist = []


klist is not necessary because key in dict1 will give you the
same but faster.

>
> for key in dict1:
> if dict1[key] > 3: # some criterion
> dict2[key] = dict1[key]
> klist.append(key)
>
> for key in klist:
> del dict1[key]
>
> print dict1
> print dict2
>
> That means that I store the keys of the items to be removed from
> the original dict in a list (klist) and subsequently remove the
> items using these keys.
>
> Is there an "even more pythonic" way?
>
> Cheers, jsaul


One solution could be:
>>> dict1 = { "a":1, "b":3, "c":5, "d":4, "e":2 }

# a little transfer-function, which deletes an item (k,v) in d and
# returns (k,v)
>>> transfer=lambda d,(k,v):[d.__delitem__(k)] and (k,v)

# transfer the items from one dict into a list and make a dict
# from it on the fly
>>> dict2=dict([transfer(dict1,(k,v)) for (k,v) in dict1.items() if v>3])
>>> dict1

{'a': 1, 'b': 3, 'e': 2}
>>> dict2

{'c': 5, 'd': 4}
>>>


Regards
Peter
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Newbie: splitting dictionary definition across two .py files kar1107@gmail.com Python 6 04-03-2006 02:37 PM
splitting one dictionary into two Raymond Hettinger Python 1 04-02-2004 03:31 PM
Re: Splitting up the definitions of a class into different files (splitting public from private)? John Dibling C++ 0 07-19-2003 04:41 PM
Re: Splitting up the definitions of a class into different files (splitting public from private)? Mark C++ 0 07-19-2003 04:24 PM
Re: Splitting up the definitions of a class into different files (splitting public from private)? John Ericson C++ 0 07-19-2003 04:03 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57