74

I have a python dictionary. Just to give out context, I am trying to write my own simple cross validation unit.

So basically what I want is to get all the values except for the given keys. And depending on the input, it returns all the values from a dictionary except to those what has been given.

So if the input is 2 and 5 then the output values doesn't have the values from the keys 2 and 5?

Yurii
  • 827
  • 2
  • 13
  • 23
frazman
  • 32,081
  • 75
  • 184
  • 269

11 Answers11

72
for key, value in your_dict.items():
    if key not in your_blacklisted_set:
        print value

the beauty is that this pseudocode example is valid python code.

it can also be expressed as a list comprehension:

resultset = [value for key, value in your_dict.items() if key not in your_blacklisted_set]
Samus_
  • 2,903
  • 1
  • 23
  • 22
25

If your goal is to return a new dictionary, with all key/values except one or a few, use the following:

exclude_keys = ['exclude', 'exclude2']
new_d = {k: d[k] for k in set(list(d.keys())) - set(exclude_keys)}

where 'exclude' can be replaced by (a list of) key(s) which should be excluded.

Dendrobates
  • 3,294
  • 6
  • 37
  • 56
17

Just for fun with sets

keys = set(d.keys())
excludes = set([...])

for key in keys.difference(excludes):
    print d[key]
aungi
  • 3
  • 2
joel3000
  • 1,249
  • 11
  • 22
16
keys = ['a', 'b']
a_dict = {'a':1, 'b':2, 'c':3, 'd':4}
[a_dict.pop(key) for key in keys]

After popping out the keys to be discarded, a_dict will retain the ones you're after.

Darren McAffee
  • 645
  • 1
  • 6
  • 10
  • This was useful for me looking to remove one known key from a dict. If only one key then simply `dict.pop('key_name')` works. Needs try-catch if `key_name` might not exist. – yeliabsalohcin Jan 05 '23 at 17:25
  • Adding `None` as a second argument: `dict.pop('key_name', None)` solves the issue where the key doesn't exist. Thanks to @kolypto here: https://stackoverflow.com/a/70785605/2523501 – yeliabsalohcin Jan 05 '23 at 17:42
10

Given a dictionary say

d = {
     2: 2, 5: 16, 6: 5,
     7: 6, 11: 17, 12: 9,
     15: 18, 16: 1, 18: 16,
     19: 17, 20: 10
     }

then the simple comprehension example would attain what you possibly desire

[v for k,v in d.iteritems() if k not in (2,5)]

This example lists all values not with keys {2,5}

for example the O/P of the above comprehension is

[5, 6, 1, 17, 9, 18, 1, 16, 17, 10]
Steve Casey
  • 9,966
  • 1
  • 20
  • 24
Abhijit
  • 62,056
  • 18
  • 131
  • 204
  • Note: from python 3 `.iteritems()` was renamed `.items()` ``` [v for k,v in d.items() if k not in (2,5)]``` – hamagust Feb 11 '22 at 20:50
3

Also, as a list comprehension using sets:

d = dict(zip(range(9),"abcdefghi"))
blacklisted = [2,5]
outputs = [d[k] for k in set(d.keys())-set(blacklisted)]
Nate
  • 12,499
  • 5
  • 45
  • 60
2

you can also use pydash - https://pydash.readthedocs.io/en/latest/

from pydash import omit
d = {'a': 1, 'b': 2, 'c': 3}
c = omit(d, 'a')
print(c) # {'b': 2, 'c': 3}
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 11 '22 at 22:44
2

How about something along the following lines:

In [7]: d = dict((i,i+100) for i in xrange(10))

In [8]: d
Out[8]: 
{0: 100,
 1: 101,
 2: 102,
 3: 103,
 4: 104,
 5: 105,
 6: 106,
 7: 107,
 8: 108,
 9: 109}

In [9]: exc = set((2, 5))

In [10]: for k, v in d.items():
   ....:     if k not in exc:
   ....:         print v
   ....:         
   ....:         
100
101
103
104
106
107
108
109
NPE
  • 486,780
  • 108
  • 951
  • 1,012
0

using exception handling

facebook_posts = [
    {'Likes': 21, 'Comments': 2}, 
    {'Likes': 13, 'Comments': 2, 'Shares': 1}, 
    {'Likes': 33, 'Comments': 8, 'Shares': 3}, 
    {'Comments': 4, 'Shares': 2}, 
    {'Comments': 1, 'Shares': 1}, 
    {'Likes': 19, 'Comments': 3}
]

total_likes = 0

for post in facebook_posts:
    try:
        total_likes = total_likes + post['Likes']
    except KeyError:
        pass
print(total_likes)

you can also use:

except KeyError: 'My Key'

but probably only good for once off use

robot
  • 1
0

Be careful of using a shallow copy if you intend to modify the resulting dict.

import copy

def copy_dict_except_keys_shallow(d:dict, exclude_keys):
  return {k: d[k] for k in set(list(d.keys())) - set(exclude_keys)}

def copy_dict_except_keys_deep(d:dict, exclude_keys):
  return {k: copy.deepcopy(d[k]) for k in set(list(d.keys())) - set(exclude_keys)}

original = {'a': 1, 'b': [1, 2, 3]}
deep = copy_dict_except_keys_deep(original, ['a'])
deep['b'].append(4)

print("Modifying the deep copy preserves the original")
print(f"original: {original}")
print(f"deep copy: {deep}")
print()

shallow = copy_dict_except_keys_shallow(original, 'a')
shallow['b'].append(4)

print("Modifying the shallow copy changes the original")
print(f"original: {original}")
print(f"shallow copy: {shallow}")
Modifying the deep copy preserves the original
original: {'a': 1, 'b': [1, 2, 3]}
deep copy: {'b': [1, 2, 3, 4]}

Modifying the shallow copy changes the original
original: {'a': 1, 'b': [1, 2, 3, 4]}
shallow copy: {'b': [1, 2, 3, 4]}
RyanHennig
  • 1,072
  • 9
  • 12
0

Here's mine:

def dict_exclude_keys(d: dict, excludes: list[str]) -> dict:
    keys = set(list(d.keys())) - set(excludes)
    return {k: d[k] for k in keys if k in d}
masroore
  • 9,668
  • 3
  • 23
  • 28