在Python中从字典中删除键并返回新字典

87

我有一本字典

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

我需要删除一个键,比如说c,并在一个函数调用中返回不含该键的字典

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

d.pop('c')将从字典中返回键值为3而不是字典本身。

如果有的话,我需要一个函数解决方案,因为这将进入综合体


d.pop('c')返回 d - Victor Castillo Torres
@VictorCastilloTorres,它返回了'c'的值,在这个例子中是3。 - Xeos
我认为这并不是 True,因为首先您删除了 c 的值,现在 d = {'a':1, 'b':2},如果您return d,它将返回 {'a':1, 'b':2} - Victor Castillo Torres
哦,我明白你的意思了。我没有意识到你所有的评论都是代码。我以为你在问 d.pop('c') 是否会返回 d :) 是的,那样可以,但我不能使用它。我需要在推导式中使用它。 - Xeos
7个回答

110

这个怎么样:

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

它被称为字典推导式,自Python 2.7起可用。

如果您使用的是早于2.7版本的Python:

dict((i,d[i]) for i in d if i!='c')

没错,完全可行。我已经用以下代码使其工作: dict(set(d.items()) - {('c', 0)}) 但这是因为我知道'c'将取什么值。你的解决方案更加全面。 - Xeos
1
结果表明,在小数据集上(我需要操作的数据集)性能大致相同。 - Xeos
1
你的答案在技术上很好,但如果你能解释一些细节,比如它是如何实际工作的,那就更好了。 - David Ferenczy Rogožan
如果遇到名称错误(“d未定义”),可以使用(lambda x=d: {key:x[key] for key in x if key != 'c'})() - Niko Pasanen
13
建议使用变量名k而不是i,因为它存储的是字典的键,而不是索引。此外,请注意可以通过k,v in f.items()迭代,从而可以使用v来引用值,而不是d[i]。最终结果为:{k: v for k, v in d.items() if k != 'c'} - tar
显示剩余2条评论

30

为什么不自己动手呢?这可能比使用字典推导式创建一个新的更快:

def without(d, key):
    new_d = d.copy()
    new_d.pop(key)
    return new_d

1
是的,那是一个解决方案。不幸的是,我被限制使用本地方法,无法添加任何自己的方法。但这个方案完全可行。 - Xeos
5
只是出于好奇,为什么你不能定义自己的函数? - Gustav Larsson
3
这是一项任务,我需要使用理解和本地函数来完成,所以不能使用外部模块。请注意,翻译后的文本不应更改原意并应易于理解。 - Xeos
3
如何提问和回答作业问题? - Clément

16

如果你需要一个能够在lambda或者推导式中使用的表达式,那么可以用这个小技巧: 创建一个包含字典和弹出元素的元组,然后再从元组中获取原始项:

(foo, foo.pop(x))[0]
例如:
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}]

请注意,这实际上修改了原始字典,所以尽管它是一种推导方式,但它并不是完全函数式的。


8
当您调用pop时,原始字典会被直接修改。
您可以从函数中返回修改后的字典。
>>> a = {'foo': 1, 'bar': 2}
>>> a.pop('foo')
1
>>> a
{'bar': 2}

5
虽然这段代码可能解决了问题,但是提供一些解释有助于提高你的帖子质量并使内容更加易懂。请记住,你正在回答未来读者的问题,这些人可能不知道你提出代码建议的原因。 - 31piy
1
不错的技巧:[a.pop('foo'),a][1] 的替代方案。实际上,这是一种我想更普遍地使用的结构。它本质上是返回一系列语句的结果。 - WestCoastProjects

1

我的解决方案

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

这将会起作用,

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

编辑 如果字典中存在该键,则此操作将删除该键,并返回不包含该键值对的字典

在Python中,有些函数会直接修改对象并返回一个值,而不是修改后的对象,{}.pop函数就是一个例子。

我们可以使用lambda函数,如下面的示例,或更通用的方式 (lambda func:obj:(func(obj) and False) or obj) 来改变这种行为,并获得预期的结果。


你的回答确实值得一些解释。请参考http://stackoverflow.com/help/how-to-answer。评论将有助于创建可搜索的内容。 - J. Chomel

0
字典推导似乎更加优雅
{k:v for k,v in d.items() if k != 'c'}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接