Behaviour of pop() for dictionaries

BlindAnagram blindanagram at nowhere.org
Tue Jun 15 05:37:03 EDT 2021


On 15/06/2021 00:11, dn wrote:
> On 15/06/2021 09.18, BlindAnagram wrote:
>> On 14/06/2021 20:43, Chris Angelico wrote:
>>> On Tue, Jun 15, 2021 at 5:41 AM BlindAnagram
> ...
> 
>> No it isn't hard to use popitem() but it evidently proved hard for me to
>> remember that it was there.
> 
> If that's a problem, you're going to love using deques with their
> 'popping from the left' and 'popping from the right' concepts!

I think the difference here is that I know I am going to have to look at 
the documentation for dequeue when I want to use it. For lists, sets and 
dictionaries, I don't expect to look at the documentation and pop() 
seemed a good bet for what I wanted to do.

> I don't know if you are ComSc student or not, but there isn't even
> consistency at the theoretical level. I first arrived at the concept of
> "queuing" and "dequeuing" (NB the latter is not the same as the Python
> Collections module "deque" library) whilst studying Queue Theory in
> Operations Research. At about the same time, my ComSc studies took me
> into "stacks".

My student days are well over (about 60 years over).

> Queues are known as FIFO constructs - "first-in, first-out".
> Stacks are somewhat the opposite: LIFO - "last-in, first-out".
> 
> The "pop" operation was defined as taking the "next" item from the queue
> or the "last" item from a stack (the opposite of "push"). However,
> between queue and stack, the term "next" refers to opposite ends of the
> (implementing in Python) list!
> 
> In fact, coming from a Burroughs mainframe, which ran on "stack
> architecture" (cf IBM's multiplicity of "ALU registers"), it came as
> something of a surprise when programming languages started allowing me
> to "pop" elements that weren't at the LIFO-end of the 'list', eg
> list.pop( 3 ) where len( list ) > 4!
> 
> 
> Next consider how the terms "next" and "element" factor into the
> thinking. If we consider a (Python) list there is an implied sequence of
> elements based upon their relative position. Notice also that the basic
> implementation of list.pop() is LIFO! Whereas, the definition of a set
> involves no concept of sequence or order - only of membership (and that
> the elements are "hashable"). Accordingly, a pop() operation returns an
> "arbitrary value", cf 'next please'.
> 
> Similarly, a dict's keys are referred-to as hashable, with the idea of
> "random access" to an element via its key (cf the "sequential access" of
> a list). Thus, we can ask to pop() a dict, but only if we provide a key
> - in which case, pop( key ) is the same as dict[ key ] except that the
> key-value pair is also removed from the dict!
> 
> Recall though, it is possible to use list.pop() without any argument.
> So, consistency has been thrown-out-the-window there as well.
> 
> Also, with LIFO in-mind, Python v3.7 brought a concept of 'sequence'
> (population order) to dicts, and thus we now have this "guarantee" in
> popitem() - and thus a memory-confusion for those of us who learned the
> original "arbitrary" definition - confusion both of dict behavior and of
> dict.popitem() specifically!
> 
> Worse confusion awaits (and referring to a conversation 'here' last
> week) Python's pop() exhibits elements of both an "expression" and of a
> "statement", ie it not only returns a value, but it affects
> (?"side-effects") the underlying collection. Thus, no pop() for strings,
> tuples, etc, because they are immutable collections!
> 
> The action of pop() is clearly inconsistent across types of collection.
> It's effect is data-structure dependent because the purposes of those
> structures are inherently different. "Consistency" would aid memory, but
> "polymorphism" can only deliver functionality according to the
> characteristics of the specific data-type!

Yes, but we can still seek consistency where it is possible

> Having entered the queue-of-life a long time ago, and shuffling ever
> closer to 'the end of the line', this memory-challenged 'silver-surfer'
> prefers to reserve pop() for straightforward stacks and lists, which
> implies quite enough inconsistency, without trying to convolute my mind
> to pop()-ing dicts, sets (or 'worse'!).
> 
> That said, whether I actually use dict.pop() or not, these 'features'
> which are consistent in name but not necessarily in arguments or
> effects, contribute to Python's great flexibility and power! Thank
> goodness for help() and the Python docs...

I don't like 'pop's at all since it meant that a valve had exploded on 
the Ferranti Pegasus that was my first encounter with computers.

     Brian


More information about the Python-list mailing list