splitting one dictionary into two

Discussion in 'Python' started by jsaul, Apr 1, 2004.

  1. jsaul

    jsaul Guest

    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, Apr 1, 2004
    #1
    1. Advertisements

  2. jsaul

    Terry Reedy Guest

    "jsaul" <> 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
     
    Terry Reedy, Apr 1, 2004
    #2
    1. Advertisements

  3. jsaul

    wes weston Guest

    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
     
    wes weston, Apr 1, 2004
    #3
  4. jsaul

    Peter Otten Guest

    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
     
    Peter Otten, Apr 1, 2004
    #4
  5. jsaul

    Larry Bates Guest

    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" <> 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
     
    Larry Bates, Apr 1, 2004
    #5
  6. jsaul

    jsaul Guest

    * 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
     
    jsaul, Apr 1, 2004
    #6
  7. jsaul

    wes weston Guest

    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
     
    wes weston, Apr 1, 2004
    #7
  8. jsaul

    Peter Abel Guest

    jsaul <> 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
     
    Peter Abel, Apr 2, 2004
    #8
    1. Advertisements

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. news.frontiernet.net
    Replies:
    6
    Views:
    1,402
    news.frontiernet.net
    Apr 16, 2004
  2. Raymond Hettinger

    splitting one dictionary into two

    Raymond Hettinger, Apr 2, 2004, in forum: Python
    Replies:
    1
    Views:
    387
    wes weston
    Apr 2, 2004
  3. David Pratt

    Splitting string into dictionary

    David Pratt, Jul 1, 2005, in forum: Python
    Replies:
    2
    Views:
    355
    John Machin
    Jul 1, 2005
  4. Robert Kern

    Re: Splitting string into dictionary

    Robert Kern, Jul 1, 2005, in forum: Python
    Replies:
    3
    Views:
    339
    Christopher Subich
    Jul 2, 2005
  5. Replies:
    6
    Views:
    461
    Adam DePrince
    Apr 3, 2006
  6. AG
    Replies:
    5
    Views:
    534
    =?iso-8859-1?q?Erik_Wikstr=F6m?=
    Jan 18, 2007
  7. erdos

    Splitting app into two apps

    erdos, Mar 15, 2007, in forum: ASP .Net
    Replies:
    2
    Views:
    323
    erdos
    Mar 15, 2007
  8. Armin
    Replies:
    12
    Views:
    1,465
    Steve Holden
    Mar 23, 2009
Loading...