86

I have a dictionary

d = {'a':1, 'b':2, 'c':3}

I need to remove a key, say c and return the dictionary without that key in one function call

{'a':1, 'b':2}

d.pop('c') will return the key value - 3 - instead of the dictionary.

I am going to need one function solution if it exists, as this will go into comprehensions

Xeos
  • 5,975
  • 11
  • 50
  • 79

7 Answers7

109

How about this:

{i:d[i] for i in d if i!='c'}

It's called Dictionary Comprehensions and it's available since Python 2.7.

or if you are using Python older than 2.7:

dict((i,d[i]) for i in d if i!='c')
David Ferenczy Rogožan
  • 23,966
  • 9
  • 79
  • 68
jh314
  • 27,144
  • 16
  • 62
  • 82
  • Yep, totally works. I have got it to work with: `dict(set(d.items()) - {('c', 0)})` But it's because I knew the value the 'c' will take. Your solution is more.. comprehensive – Xeos Jul 16 '13 at 00:10
  • 1
    Turns out performance on small data sets (what I need to operate on) is around the same. – Xeos Jul 16 '13 at 00:30
  • `dict((i,d[i]) for i in d if i!='c')` -- Brownie points for you for not creating another intermediate list/tuple :) – haridsv Apr 02 '16 at 14:30
  • Dict comprehension is available since Python 2.7 – Daniel Hepper Aug 25 '16 at 10:02
  • 1
    Your answer is technically good, but it would be better if you can explain a bit some details, e.g. how it actually works. – David Ferenczy Rogožan Apr 06 '17 at 14:26
  • In case of running into NameErrors ("d is not defined"), it is possible to use `(lambda x=d: {key:x[key] for key in x if key != 'c'})()`. – Niko Föhr Feb 14 '18 at 11:03
  • 12
    I recommend using a variable name of `k` rather than `i` because it is storing a dict key, not an index. Also note that you can iterate over `k, v in f.items()`, allowing you to refer to the value with `v` instead of `d[i]`. In the end: `{k: v for k, v in d.items() if k != 'c'}` – tar Feb 04 '20 at 20:19
30

Why not roll your own? This will likely be faster than creating a new one using dictionary comprehensions:

def without(d, key):
    new_d = d.copy()
    new_d.pop(key)
    return new_d
Gustav Larsson
  • 8,199
  • 3
  • 31
  • 51
  • 1
    Yeah, that is a solution. Unfortunetly I am stuck with native methods and I can't add any of my own. But this totally would work. – Xeos Jul 16 '13 at 00:13
  • 5
    Just out of curiosity, how come you can't define your own functions? – Gustav Larsson Jul 16 '13 at 00:17
  • 3
    It's an assignment I need to complete using only comprehensions and native functions, so no external modules as well. – Xeos Jul 16 '13 at 00:28
  • 3
    [How do I ask and answer homework questions?](https://meta.stackoverflow.com/q/334822) – Clément Aug 12 '21 at 22:07
15

If you need an expression that does this (so you can use it in a lambda or comprehension) then you can use this little hack trick: create a tuple with the dictionary and the popped element, and then get the original item back out of the tuple:

(foo, foo.pop(x))[0]

For example:

ds = [{'a': 1, 'b': 2, 'c': 3}, {'a': 4, 'b': 5, 'c': 6}]
[(d, d.pop('c'))[0] for d in ds]
assert ds == [{'a': 1, 'b': 2}, {'a': 4, 'b': 5}]

Note that this actually modifies the original dictionary, so despite being a comprehension, it's not purely functional.

z0r
  • 8,185
  • 4
  • 64
  • 83
7

When you invoke pop the original dictionary is modified in place.

You can return that one from your function.

>>> a = {'foo': 1, 'bar': 2}
>>> a.pop('foo')
1
>>> a
{'bar': 2}
silviot
  • 4,615
  • 5
  • 38
  • 51
Felix Yuan
  • 173
  • 2
  • 5
  • 1
    Nice trick: an alternative to `[a.pop('foo'),a][1]` . actually this is a construct i'd like to use more generally. it is essentially returning the result of a series of statement – WestCoastProjects Mar 12 '21 at 22:14
1

solution from me

item = dict({"A": 1, "B": 3, "C": 4})
print(item)
{'A': 1, 'B': 3, 'C': 4}

new_dict = (lambda d: d.pop('C') and d)(item)
print(new_dict)
{'A': 1, 'B': 3}
0

this will work,

(lambda dict_,key_:dict_.pop(key_,True) and dict_)({1:1},1)

EDIT this will drop the key if exist in the dictionary and will return the dictionary without the key,value pair

in python there are functions that alter an object in place, and returns a value instead of the altered object, {}.pop function is an example.

we can use a lambda function as in the example, or more generic below (lambda func:obj:(func(obj) and False) or obj) to alter this behavior, and get a the expected behavior.

sinaiy
  • 106
  • 9
  • "Your answer certainly is worth a little explanation. Kindly refer to http://stackoverflow.com/help/how-to-answer . Comments would help create searchable content. " – J. Chomel Mar 27 '17 at 12:11
0

Dict comprehension seems to be more elegant

{k:v for k,v in d.items() if k != 'c'}
minglyu
  • 2,958
  • 2
  • 13
  • 32