Popping key causes dict derived from object to revert to object

avi.e.gross at gmail.com avi.e.gross at gmail.com
Mon Mar 25 12:04:48 EDT 2024


I am glad, Lori, you found a solution another way.

Actually, Lori, I think you were right in looking for a built-in method that complements pop() by returning everything else other than the item mentioned. There are philosophical and practical considerations that were no doubt considered and a reality that the functionality did exist albeit not in a pipelined format.

Consider a language like LISP which sort of processed lists of things in which a major concept was getting the first item or getting all the rest. Lots of LISP programs had complex structures using CAR() and CDR() nested various ways to say extract the third item as CAR(CDR(CDR(X))) to the point where some commonly used combos became functions with names like CADDR().

There are again many languages where functions or methods are available that include an exclusion variant from a collection perhaps by doing something as simple as using a minus sign to indicate what to remove, as is commonly done in R to remove a column in a data.frame while keeping the order of the remaining columns the same.

Lots of languages had similar concepts about ordered data structures but dictionaries may be a bit of something else and initially in Python were not guaranteed to have any kind of order. Python dicts are more like unordered sets. 

So although there remains a concept of not first/rest but this/rest,  I suspect there was some thought about the process that ended in deciding not to supply some functionality. When you use pop() on something like a large dictionary, the original is left intact and is ignored and a copy of a single element is made and returned. To do  the opposite and return the rest has two choices. One is to make a big copy of the rest of the dictionary and the other is to use del internally and return the modified dict. The functions you could write do the latter.

So why not add one or more methods to do that? Who knows? But I think some may have considered it not needed including some who felt no need for a pipeline method when del would do. Another consideration was the common idiom for iterating on a collection. Besides pop() you can get lists of dictionary entries, keys or values that you can work with and you can even iterate with "for key in dict: ..."

Given how many ways common things can be done, and given that adding too many methods has costs including new users not understanding all the nuanced differences, this fairly useful functionality was left out.

Unfortunately, I think they were wrong here as instead we hear often from people like you who assume things would work other ways. I still think it would be simple enough to have had a .removekeys(keys) that would work in a pipeline to modify the dict by removing one or more items and perhaps another .removevalues(values) but at some point you may keep adding methods nobody ever uses. The reality is that many trivial one-liner comprehensions can easily do many such things using iteration. 

But many simply do not work well in pipelined fashion and thus may need to be embedded in a method of your own by subclassing dict or rolling your own.



-----Original Message-----
From: Loris Bennett <loris.bennett at fu-berlin.de> 
Sent: Monday, March 25, 2024 2:45 AM
To: avi.e.gross at gmail.com
Cc: python-list at python.org
Subject: Re: Popping key causes dict derived from object to revert to object

<avi.e.gross at gmail.com> writes:

> Loris wrote:
>
> "Yes, I was mistakenly thinking that the popping the element would leave
> me with the dict minus the popped key-value pair.  Seem like there is no
> such function."
>
> Others have tried to explain and pointed out you can del and then use the
> changed dict.
>
> But consider the odd concept of writing your own trivial function.
>
> def remaining(adict, anitem):
>   _ = adict.pop(anitem)
>   # alternatively duse del on dict and item
>   return adict
>
>
>>>> remaining({"first": 1, "second": 2, "third": 3}, "second")
> {'first': 1, 'third': 3}
>
>
> Or do you want to be able to call it as in dict.remaining(key) by
> subclassing your own variant of dict and adding a similar method?

No, 'del' does indeed do what I wanted, although I have now decided I
want something else :-)  Nevertheless it is good to know that 'del'
exists, so that I don't have to reinvent it.

Cheers,

Loris

-- 
This signature is currently under constuction.



More information about the Python-list mailing list