59

我想创建一个函数,该函数返回字典的副本,不包括列表中指定的键。

考虑这本词典:

my_dict = {
    "keyA": 1,
    "keyB": 2,
    "keyC": 3
}

调用without_keys(my_dict, ['keyB', 'keyC'])应该返回:

{
    "keyA": 1
}

我想用简洁的字典理解在一行中做到这一点,但我遇到了麻烦。我的尝试是这样的:

def without_keys(d, keys):
    return {k: d[f] if k not in keys for f in d}

这是无效的语法。我怎样才能做到这一点?

4

7 回答 7

63

你很接近,试试下面的片段:

>>> my_dict = {
...     "keyA": 1,
...     "keyB": 2,
...     "keyC": 3
... }
>>> invalid = {"keyA", "keyB"}
>>> def without_keys(d, keys):
...     return {x: d[x] for x in d if x not in keys}
>>> without_keys(my_dict, invalid)
{'keyC': 3}

基本上,if k not in keys在上述情况下,将在 dict 理解结束时进行。

于 2015-07-15T15:01:47.563 回答
34

在您的字典理解中,您应该遍历您的字典(不是k,也不确定那是什么)。例子 -

return {k:v for k,v in d.items() if k not in keys}
于 2015-07-15T15:02:05.237 回答
8

这应该适合你。

def without_keys(d, keys):
    return {k: v for k, v in d.items() if k not in keys}
于 2015-07-15T15:01:52.063 回答
5

甚至更短。显然,python 3 可以让你list从 a 中“减去” a dict_keys

def without_keys(d, keys):
    return {k: d[k] for k in d.keys() - keys}
于 2020-09-17T18:50:03.513 回答
1

对于那些不喜欢列表推导的人,这是我的版本:

def without_keys(d, *keys):
     return dict(filter(lambda key_value: key_value[0] not in keys, d.items()))

用法:

>>> d={1:3, 5:7, 9:11, 13:15}
>>> without_keys(d, 1, 5, 9)
{13: 15}
>>> without_keys(d, 13)
{1: 3, 5: 7, 9: 11}
>>> without_keys(d, *[5, 7])
{1: 3, 13: 15, 9: 11}
于 2017-01-02T06:50:11.280 回答
0

您可以将此概括为嵌套字典解决方案

def copy_dict(data, strip_values=False, remove_keys=[]):
    if type(data) is dict:
        out = {}
        for key, value in data.items():
            if key not in remove_keys:
                out[key] = copy_dict(value, strip_values=strip_values, remove_keys=remove_keys)
        return out
    else:
        return [] if strip_values else data

这种递归解决方案适用于嵌套字典,并从整个嵌套结构中删除不需要的键。它还使您能够返回只有键而没有值的嵌套。

于 2021-11-17T19:54:55.480 回答
0

你的oneliner

my_dict = {"keyA": 1, "keyB": 2, "keyC": 3}
(lambda keyB, keyC, **kw: kw)(**my_dict)

返回{'keyA': 1}。不是很 Pythonic 和动态,但是 hacky 和简短。它使用函数参数的 dict 解包(解构赋值)。

另请参阅 https://stackoverflow.com/a/53851069/11769765

于 2021-11-29T14:33:29.460 回答