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 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". 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! 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... -- Regards, =dn -- https://mail.python.org/mailman/listinfo/python-list