Can we have a .discard() for dictionary please

Ref: https://discuss.python.org/t/can-we-have-a-delete-for-dictionary-please/

In the ref I was given a solution for my problem, which while usable, is not thematically correct.

.pop() is for removing and retrieving an existing item (so a .get() and ‘del item’ combined). At no point did I look further into .pop() as it’s job is not to delete. It turns out it does have a ‘default’ so it can be used (abused ??) for this purpose.

thanks
Peter

1 Like

What are the semantics of .discard method?
How is it different from del dict[key]

I feel as though pop() for this purpose is fine and makes sense to at least me.

More options that already exist:

try:
    del d['key']
except KeyError:
    pass
from contextlib import suppress

with suppress(KeyError):
    del d['key']
if 'key' in d:
    del d['key']

and like you mentioned:

d.pop('key', None)

I’m not really sure I see the value in adding more ways to do it directly in the base language with so many other available ways already.

10 Likes

From the original post, it’s to not raise an error if the key doesn’t exist.

I think this is a rare need (no code I’ve written or recall seeing needs this behavior), and if I did need it I’d use try/except around del.

3 Likes

And it’s equivalent in behavior to dict.pop(key, None) (except that .discard might not return the value.)

I asked because I think that an idea should be self contained and not need references to other sources.

That absolutely is its job.

4 Likes

Completely agree. That’s the only reason I responded, so others wouldn’t have to go look it up, like I had to!

2 Likes

I myself often did. And I never saw a reason not to use dict.pop :person_shrugging:

2 Likes

Discoverability is one reason. That dict.pop takes a optional default is easy to miss. set.pop and list.pop don’t, but there’s set.discard. If you know about set.discard then you’ll naturally look for a dict equivalent by the same name.

That’s what I did anyway. I’ve written plenty of try/del/except KeyError’s, it never occuring to me that dict.pop could serve the same purpose.

1 Like

try/del/except is a perfectly cromulent idiom, and having now learned it can be done with .pop(), you can choose to use that in the future. Wishing you’d known earlier might be an argument for proposing an improvement to the documentation, but not for adding redundant language feature.

6 Likes

I’m not sure I wish I’d learnt earlier. Using a function that returns a value for its side-effect, and then ignoring the value returned, is something I like to avoid. And you have to supply an expression which is ignored: Writing the statement aDict.pop(key, 42 .bit_count()) has the same effect as aDict.pop(key, None) (if a bit slower). Arguably, try/del/except is cleaner code.

Writing your own discard function is pretty easy, and a perfectly reasonable alternative if your main concern is a dislike of the style aspects of the standard approaches.

4 Likes

Standard? @csm10495 enumerated 4 different approaches. Neither of them are the one obvious way to do it.

OK, “existing” rather than “standard”. But I was specifically responding to your comment that you disliked using pop. If you’re happy using try/del/except then that’s fine.

Actually I find all 4 approaches about equally suboptimal. But I’m always happy writing Python :grinning:

1 Like

Well, this is now an aesthetic argument, not one about discoverability for people familiar with sets. That’s all well and good, but adding a fifth way to do it also has a counterargument grounded in aesthetics.

1 Like

Well, that “side-effect” is the first effect mentioned in its doc: “If key is in the dictionary, remove it and return its value, else return default.” And the name suggests it, too. If I didn’t know what it does, then just from the name “pop”, I’d more likely guess that it removes the item and doesn’t return it than the other way around. Like in C++, for example.

I think you’re looking at this function upside down. Its intended use case is to remove an item. It’s not a getter. It is a mutate operation. It just happens to also return the removed value because that’s how you can interrogate exactly what it did after the fact. If you don’t care, then don’t use the result.

6 Likes

I’ve removed some replies that were getting off topic by being extremely pedantic about an unrelated side topic. As users, please be aware not to start that in the first place, but also not to continue replying to it if you see it. It makes topics difficult to follow or participate in. Start a new topic if you want to discuss something new. Flag posts that go off topic to be moved.

9 Likes