By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,677 Members | 1,110 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,677 IT Pros & Developers. It's quick & easy.

pop method question

P: n/a
Howdy Folks,

I was just playing around in IDLE at the interactive prompt and typed
in dir({}) for the fun of it. I was quite surprised to see a pop
method defined there. I mean is that a misnomer or what? From the
literature, pop is supposed to be an operation defined for a stack
data structure. A stack is defined to be an "ordered" list data
structure. Dictionaries in Python have no order but are sequences.
Now, does anyone know why the python core has this pop method
implemented for a dictionary type?

I realize that in this context it is used for removing a specific key
from the current dictionary object. But why call it pop and not
something more intuitive like remove or delete?

Thanks for the clarification in advance :).

--Nick


Mar 3 '07 #1
Share this Question
Share on Google+
25 Replies


P: n/a
Nicholas Parsons <pa***************@gmail.comwrote:
I realize that in this context it is used for removing a specific key
from the current dictionary object. But why call it pop and not
something more intuitive like remove or delete?
I wasn't a python programmer back than, but I'd guess it's
because pop not just removes the key, it returns the value as
well.
--
Web (en): http://www.no-spoon.de/ -*- Web (de): http://www.frell.de/
Mar 3 '07 #2

P: n/a
Nicholas Parsons <pa***************@gmail.comwrites:
I was just playing around in IDLE at the interactive prompt and typed
in dir({}) for the fun of it. I was quite surprised to see a pop
method defined there. I mean is that a misnomer or what? From the
literature, pop is supposed to be an operation defined for a stack
data structure. A stack is defined to be an "ordered" list data
structure. Dictionaries in Python have no order but are sequences.
Now, does anyone know why the python core has this pop method
implemented for a dictionary type?
Try typing:

help({}.pop)
Mar 3 '07 #3

P: n/a

On Mar 3, 2007, at 3:49 PM, Paul Rubin wrote:
Nicholas Parsons <pa***************@gmail.comwrites:
>I was just playing around in IDLE at the interactive prompt and typed
in dir({}) for the fun of it. I was quite surprised to see a pop
method defined there. I mean is that a misnomer or what? From the
literature, pop is supposed to be an operation defined for a stack
data structure. A stack is defined to be an "ordered" list data
structure. Dictionaries in Python have no order but are sequences.
Now, does anyone know why the python core has this pop method
implemented for a dictionary type?

Try typing:

help({}.pop)
--
http://mail.python.org/mailman/listinfo/python-list
Thanks, that gives a more details explanation of what the behavior is
but doesn't answer my question above :(

Mar 3 '07 #4

P: n/a
On Sat, 03 Mar 2007 15:56:39 -0500, Nicholas Parsons wrote:
>
On Mar 3, 2007, at 3:49 PM, Paul Rubin wrote:
>Nicholas Parsons <pa***************@gmail.comwrites:
>>I was just playing around in IDLE at the interactive prompt and typed
in dir({}) for the fun of it. I was quite surprised to see a pop
method defined there. I mean is that a misnomer or what? From the
literature, pop is supposed to be an operation defined for a stack
data structure. A stack is defined to be an "ordered" list data
structure. Dictionaries in Python have no order but are sequences.
Now, does anyone know why the python core has this pop method
implemented for a dictionary type?

Try typing:

help({}.pop)
--
http://mail.python.org/mailman/listinfo/python-list

Thanks, that gives a more details explanation of what the behavior is
but doesn't answer my question above :(
Just because pop can be defined for an ordered stack doesn't mean pop
can't be generalized to other data types too.

I personally don't see that pop has any advantage, especially since the
most useful example

while some_dict:
do_something_with(some_dict.pop())

doesn't work. Instead you have to write this:

for key in some_dict.keys():
# can't iterate over the dictionary directly!
do_something_with(some_dict.pop(key))

which is hardly any saving over:

for key in some_dict.keys():
# can't iterate over the dictionary directly!
do_something_with(some_dict[key])
del some_dict[key]
To my mind, having to supply a key to dict.pop makes it rather pointless.
--
Steven.

Mar 3 '07 #5

P: n/a
On Saturday 03 March 2007 15:56, Nicholas Parsons
wrote:
On Mar 3, 2007, at 3:49 PM, Paul Rubin wrote:
Nicholas Parsons <pa***************@gmail.com>
writes:
I was just playing around in IDLE at the
interactive prompt and typed in dir({}) for
the fun of it. I was quite surprised to see
a pop method defined there. I mean is that
a misnomer or what? From the literature,
pop is supposed to be an operation defined
for a stack data structure. A stack is
defined to be an "ordered" list data
structure. Dictionaries in Python have no
order but are sequences. Now, does anyone
know why the python core has this pop method
implemented for a dictionary type?

aDict.pop(theKey)
'produce the value'

pop removes the key:value and produces the value
as results

jim-on-linux
http:\\www.inqvista.com


Try typing:

help({}.pop)
--
http://mail.python.org/mailman/listinfo/pytho
n-list

Thanks, that gives a more details explanation
of what the behavior is but doesn't answer my
question above :(
Mar 3 '07 #6

P: n/a
On Sat, 03 Mar 2007 18:13:18 -0500, jim-on-linux wrote:
On Saturday 03 March 2007 15:56, Nicholas Parsons
wrote:
>On Mar 3, 2007, at 3:49 PM, Paul Rubin wrote:
Nicholas Parsons <pa***************@gmail.com>
writes:
>I was just playing around in IDLE at the
interactive prompt and typed in dir({}) for
the fun of it. I was quite surprised to see
a pop method defined there. I mean is that
a misnomer or what? From the literature,
pop is supposed to be an operation defined
for a stack data structure. A stack is
defined to be an "ordered" list data
structure. Dictionaries in Python have no
order but are sequences. Now, does anyone
know why the python core has this pop method
implemented for a dictionary type?


aDict.pop(theKey)
'produce the value'

pop removes the key:value and produces the value
as results

Amazing. Absolutely amazing. Just goes to show that the ability to use
Linux doesn't require the sense to READ THE REST OF THE POST BEFORE
HITTING SEND. Not even the rest of the thread, just the post.

The Original Poster already knows that.
--
Steven.

Mar 3 '07 #7

P: n/a
Steven D'Aprano wrote:
I personally don't see that pop has any advantage, especially since the
most useful example

while some_dict:
do_something_with(some_dict.pop())

doesn't work. Instead you have to write this:

for key in some_dict.keys():
# can't iterate over the dictionary directly!
do_something_with(some_dict.pop(key))

which is hardly any saving over:

for key in some_dict.keys():
# can't iterate over the dictionary directly!
do_something_with(some_dict[key])
del some_dict[key]
To my mind, having to supply a key to dict.pop makes it rather pointless.


I've used it in something like this and found it worthwhile:

for akey in dict1:
if some_condition(akey):
dict2[akey] = dict2.pop(akey)

Which necessitates a key is a little cleaner than your latter example.
Mar 3 '07 #8

P: n/a
James Stroud <js*****@mbi.ucla.eduwrites:
for akey in dict1:
if some_condition(akey):
dict2[akey] = dict2.pop(akey)

Which necessitates a key is a little cleaner than your latter example.
Yeah, I also think removing keys from a dict while iterating over it
(like in Steven's examples) looks a bit dangerous dangerous.

Assuming you meant "dict1.pop" instead ot dict2.pop above, your
example might be written

dict2 = dict((k, dict1.pop(k)) for k in dict1 if some_condition(k))

avoiding some namespace pollution etc.
Mar 3 '07 #9

P: n/a
On Sat, 03 Mar 2007 23:22:10 +0000, James Stroud wrote:
>To my mind, having to supply a key to dict.pop makes it rather pointless.



I've used it in something like this and found it worthwhile:

for akey in dict1:
if some_condition(akey):
dict2[akey] = dict2.pop(akey)
Surely that's a no-op? You pop the value, than add it back again.

Or do you mean dict2[akey] = dict1.pop(akey)?

If so, are you sure that works? When I try it, I get "RuntimeError:
dictionary changed size during iteration". You would need to take a copy
of the keys and iterate over that.

for key in dict1.keys():
if some_condition(key):
dict2[key] = dict1.pop(key)

--
Steven.

Mar 3 '07 #10

P: n/a
On Sat, 03 Mar 2007 15:36:14 -0800, Paul Rubin wrote:
James Stroud <js*****@mbi.ucla.eduwrites:
>for akey in dict1:
if some_condition(akey):
dict2[akey] = dict2.pop(akey)

Which necessitates a key is a little cleaner than your latter example.

Yeah, I also think removing keys from a dict while iterating over it
(like in Steven's examples) looks a bit dangerous dangerous.
It is dangerous. That's why I didn't do it.

I very carefully iterated over a list, not the dictionary, and in fact put
in a comment explicitly saying that you can't iterate over the dictionary:

for key in some_dict.keys():
# can't iterate over the dictionary directly!
do_something_with(some_dict.pop(key))
If you try to iterate over the dictionary directly, you get a RuntimeError
exception when the dictionary changes size. Unfortunately, the exception
isn't raised until AFTER the dictionary has changed size.
>>D = {1:1, 2:2}
for key in D:
.... D.pop(key)
....
1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: dictionary changed size during iteration
>>D
{2: 2}
That's a gotcha to watch out for: the exception isn't raised until
the damage is done.
Assuming you meant "dict1.pop" instead ot dict2.pop above, your
example might be written

dict2 = dict((k, dict1.pop(k)) for k in dict1 if some_condition(k))

avoiding some namespace pollution etc.
You get a RuntimeError exception when dict1 changes size.

You know, if I were easily offended, I'd be offended that you accused _me_
of writing dangerous code when my code both worked and worked safely,
while your code failed and did damage when it did so (dict1 irretrievably
loses an item).

*wink*

--
Steven.

Mar 4 '07 #11

P: n/a
Steven D'Aprano wrote:
On Sat, 03 Mar 2007 23:22:10 +0000, James Stroud wrote:
>>To my mind, having to supply a key to dict.pop makes it rather pointless.


I've used it in something like this and found it worthwhile:

for akey in dict1:
if some_condition(akey):
dict2[akey] = dict2.pop(akey)

Surely that's a no-op? You pop the value, than add it back again.

Or do you mean dict2[akey] = dict1.pop(akey)?

If so, are you sure that works? When I try it, I get "RuntimeError:
dictionary changed size during iteration". You would need to take a copy
of the keys and iterate over that.

for key in dict1.keys():
if some_condition(key):
dict2[key] = dict1.pop(key)
Yes. You are right, both in the typo and using keys().

James
Mar 4 '07 #12

P: n/a
[Nicholas Parsons]
Dictionaries in Python have no order but are sequences.
Now, does anyone know why the python core has this pop method
implemented for a dictionary type?

I realize that in this context it is used for removing a specific key
from the current dictionary object. But why call it pop and not
something more intuitive like remove or delete?
The naming for pop() method followed from the naming of the previously
existing popitem() method. Neither "remove" nor "delete" would have
been a good name for a method that looked-up and returned a value as
well as mutating the dictionary. The word "pop" on the other hand
strongly suggests both retrieval and mutation.

The notion that "pop" is only defined for stack operations is somewhat
pedantic. We have also successfully used the name for sets, dicts,
and deques (success meaning that most people just "get it" and are
able to learn, use, read the name without difficultly).

The rationale for the pop() method was that the pattern "v=d[k]; del
d[k]" could be collapsed to a single call, eliminating a two
successive look-ups of the same key. Looking back, this rationale is
questionable because 1) the second lookup is not expensive because the
first lookup put the relevant hash entries in the cache, and 2) the
lookup/delete pattern for dictionaries does not seem to arise often in
practice (it does come-up every now and then in the context of set
operations).

There was also a notion that threaded programming would benefit by
having lookup-then-delete as an atomic transaction. It is unknown to
me whether that purported benefit has ever been realized.
Raymond Hettinger

Mar 4 '07 #13

P: n/a
Raymond Hettinger <py****@rcn.comwrote:
...
The notion that "pop" is only defined for stack operations is somewhat
pedantic.
Worse: it's totally wrong. It's also defined for eyes, as a musical
genre, as a kind of soda, as an avant-garde artistic movement of the
'50s, for baloons, as a parent of the male persuasion, for email
reading, and moreover it's often used to refer to Persistent Organic
Pollutants or Points Of Presence -- not forgetting weasels, either.
Alex
Mar 4 '07 #14

P: n/a
Steven D'Aprano <st***@REMOVE.THIS.cybersource.com.auwrote:
...
while some_dict:
do_something_with(some_dict.pop())

doesn't work. Instead you have to write this:
You have to use .popitem for this -- that's what's it's for...
Alex
Mar 4 '07 #15

P: n/a
Hi Raymond,

Thank you for your clarification below. I was just using "remove"
and "delete" as possible alternatives to the name "pop" without much
contemplation. Like you say below, it begs the question as to why
not have two separate operations for dictionaries (retrieval of value
from key followed by deletion of key) instead of one method.

I'm not sure I agree with you said about the pedantic usage of pop.
I would rather have a term mean one thing instead of several causing
ambiguity. Just from my computer science background when I see pop
(), I think of a stack data structure. Why muddle the waters by
introducing another meaning for the term? There are plenty of other
words to use that could describe the behavior exhibited by the
dictionary operation of removing a key and returning its value. The
notion of a stack and pop() and push() methods for it are very
important from a historical perspective and is not just some fad.

But then again, there are other examples of ambiguity in the python
language such as allowing operators like '+' to be overloaded. Why
not just have a "add()" method like Java? Of course Java does cheat
a little by overloading the '+' operator for string objects but that
is a built-in feature of language. Also some people find '+' more
appealing to the eye than a method call like add() in their code.

Even in the case of C, we have some ambiguity with the dangling if
statement. So I guess you can't win for trying :).

Just call me a purist and think of me as someone who likes
consistency. Python is here to stay and no language is perfect...

--Nick

On Mar 3, 2007, at 7:32 PM, Raymond Hettinger wrote:
[Nicholas Parsons]
> Dictionaries in Python have no order but are sequences.
Now, does anyone know why the python core has this pop method
implemented for a dictionary type?

I realize that in this context it is used for removing a specific key
from the current dictionary object. But why call it pop and not
something more intuitive like remove or delete?

The naming for pop() method followed from the naming of the previously
existing popitem() method. Neither "remove" nor "delete" would have
been a good name for a method that looked-up and returned a value as
well as mutating the dictionary. The word "pop" on the other hand
strongly suggests both retrieval and mutation.

The notion that "pop" is only defined for stack operations is somewhat
pedantic. We have also successfully used the name for sets, dicts,
and deques (success meaning that most people just "get it" and are
able to learn, use, read the name without difficultly).

The rationale for the pop() method was that the pattern "v=d[k]; del
d[k]" could be collapsed to a single call, eliminating a two
successive look-ups of the same key. Looking back, this rationale is
questionable because 1) the second lookup is not expensive because the
first lookup put the relevant hash entries in the cache, and 2) the
lookup/delete pattern for dictionaries does not seem to arise often in
practice (it does come-up every now and then in the context of set
operations).

There was also a notion that threaded programming would benefit by
having lookup-then-delete as an atomic transaction. It is unknown to
me whether that purported benefit has ever been realized.
Raymond Hettinger

--
http://mail.python.org/mailman/listinfo/python-list
Mar 4 '07 #16

P: n/a
Nick,

In regards to stack-like objects, pop() implies mutation of the
reciever and returning the item 'popped' off the stack. The same
_semantic_ meaning can be used for pop() regarding dictionaries, even
though the _implementation_ would be different: dict.pop(key) mutates
the reciever and returns the value associated with the key.

Regards,
Jordan

Mar 4 '07 #17

P: n/a
Dennis Lee Bieber <wl*****@ix.netcom.comwrites:
"""
I before E
Except after C
Or when sounded as A
As in Neighbor and Weigh
"""
Yes, like the "A" sound in "weird" or "ceiling".

--
\ "Most people don't realize that large pieces of coral, which |
`\ have been painted brown and attached to the skull by common |
_o__) wood screws, can make a child look like a deer." -- Jack Handey |
Ben Finney

Mar 4 '07 #18

P: n/a
Ben Finney <bi****************@benfinney.id.auwrote:
Dennis Lee Bieber <wl*****@ix.netcom.comwrites:
"""
I before E
Except after C
Or when sounded as A
As in Neighbor and Weigh
"""

Yes, like the "A" sound in "weird" or "ceiling".
"ceiling" falls under the "except after C" exception.

"weird" is, of course, weird (as most of English)...
Alex
Mar 4 '07 #19

P: n/a
"Alex Martelli" <al***@mac.comwrote:
Raymond Hettinger <py****@rcn.comwrote:
...
The notion that "pop" is only defined for stack operations is somewhat
pedantic.

Worse: it's totally wrong. It's also defined for eyes, as a musical
genre, as a kind of soda, as an avant-garde artistic movement of the
'50s, for baloons, as a parent of the male persuasion, for email
reading, and moreover it's often used to refer to Persistent Organic
Pollutants or Points Of Presence -- not forgetting weasels, either.
One should never forget the pawning of weasels.

Then there is the contrary meaning - instead of "take out" it can
mean "put in" - Just pop it in the oven, there's a dear...

- Hendrik

Mar 4 '07 #20

P: n/a
In <ma***************************************@python. org>, Nicholas
Parsons wrote:
Just from my computer science background when I see pop(), I think of a
stack data structure.
Then question your presumptions. There are also many people thinking
`list` must be something with nodes and pointers when they see the
interface and usage of Python lists.
But then again, there are other examples of ambiguity in the python
language such as allowing operators like '+' to be overloaded. Why not
just have a "add()" method like Java?
Why does this remove ambiguity? I even would expect different behaviour
from both. I expect the ``+`` operator to return either an immutable or
entirely new object, while `add()` can be something on containers that
mutates the object.

Ciao,
Marc 'BlackJack' Rintsch
Mar 4 '07 #21

P: n/a
Hi Jordan,

That is true what you say about pop() behavior with stack-like
objects. But the definition of pop() for a stack-like structure is
stronger than that. A stack is a LIFO data structure. Therefore the
pop() operation is defined to not only mutate the receiver and return
the item popped but also ensure that the LAST item in the stack is
removed. This makes perfect sense for a list type in python since
lists are mutable sequences that have a specified order. But for
dictionaries this does not hold since they are unordered sequences by
definition. So for dictionaries it would not make sense for a
programmer to simulate a stack-like type.

While we're on the subject I'm also curious as to why the author of
the built-in list class called the method "append" to add an element
to the end of a list and not something like "push". But this is not
really much of a problem if the programmer could create an alias for
it. Is it possible to do this in python? I know you can do it in
ruby and even override methods and attributes in an existing built-in
class like String for instance.

--Nick


On Mar 3, 2007, at 10:40 PM, MonkeeSage wrote:
Nick,

In regards to stack-like objects, pop() implies mutation of the
reciever and returning the item 'popped' off the stack. The same
_semantic_ meaning can be used for pop() regarding dictionaries, even
though the _implementation_ would be different: dict.pop(key) mutates
the reciever and returns the value associated with the key.

Regards,
Jordan

--
http://mail.python.org/mailman/listinfo/python-list
Mar 4 '07 #22

P: n/a

On Mar 4, 2007, at 4:38 AM, Marc 'BlackJack' Rintsch wrote:
In <ma***************************************@python. org>, Nicholas
Parsons wrote:
>Just from my computer science background when I see pop(), I think
of a
stack data structure.

Then question your presumptions. There are also many people thinking
`list` must be something with nodes and pointers when they see the
interface and usage of Python lists.
Good point :).
>
>But then again, there are other examples of ambiguity in the python
language such as allowing operators like '+' to be overloaded.
Why not
just have a "add()" method like Java?

Why does this remove ambiguity? I even would expect different
behaviour
from both. I expect the ``+`` operator to return either an
immutable or
entirely new object, while `add()` can be something on containers that
mutates the object.

This is true. As long as the language (be it Java, Python, X) itself
remains consistent over time, then this should be fine.
>
Ciao,
Marc 'BlackJack' Rintsch
--
http://mail.python.org/mailman/listinfo/python-list
Mar 4 '07 #23

P: n/a
On Sun, 04 Mar 2007 07:36:50 -0500, Nicholas Parsons wrote:
Hi Jordan,

That is true what you say about pop() behavior with stack-like
objects. But the definition of pop() for a stack-like structure is
stronger than that.
That's okay, we're not talking about pop for stack-like structures, we're
talking about pop for dictionaries.

A stack is a LIFO data structure. Therefore the
pop() operation is defined to not only mutate the receiver and return
the item popped but also ensure that the LAST item in the stack is
removed.
Not so. Pop can also be defined to take an argument telling the data
structure (not necessarily a stack) which item to remove.

Pop can also operate on queues, in which case it removes the FIRST item in
the queue.

Pop can also be defined for dequeues (double-ended queue), in which case
it can remove from either the first or the last position.

Pop can also be defined for balloons, which is what they do when you stick
a pin in them.
This makes perfect sense for a list type in python since
lists are mutable sequences that have a specified order. But for
dictionaries this does not hold since they are unordered sequences by
definition.
That's okay, since unordered sequences can define pop too. Obviously pop
for a dictionary has to be defined slightly differently, but the essential
characteristics -- remove an item and return it -- remain the same.

So for dictionaries it would not make sense for a
programmer to simulate a stack-like type.
Dictionaries don't simulate stacks.

We can talk about pushing a value onto a stack, and about pushing a
value into a register, and yet registers are not stacks. We use the
same word, multiply, for both scalar multiplication (3*5=15), matrix
multiplication, and mixed scalar-to-matrix multiplication, even though
they are quite different. (For starters, XY = YX if X and Y are both
scalars, but not if they are matrices.)

We use "concatenate" to describe the different procedures of joining
linked lists, arrays and strings. We talk about "inserting" into linked
lists, B-trees, heaps, arrays and priority queues.

Why shouldn't we talk about popping a value from a dictionary?

While we're on the subject I'm also curious as to why the author of
the built-in list class called the method "append" to add an element
to the end of a list and not something like "push".
Well, gosh, I really don't know what they were thinking, using "append" as
the name of the method that, um, APPENDS an item to the end of a list. How
confusing is that?

But this is not
really much of a problem if the programmer could create an alias for
it.
It isn't a problem at all.

--
Steven.

Mar 4 '07 #24

P: n/a
In article <ma***************************************@python. org>,
Ben Finney <bi****************@benfinney.id.auwrote:
>Dennis Lee Bieber <wl*****@ix.netcom.comwrites:
>>
"""
I before E
Except after C
Or when sounded as A
As in Neighbor and Weigh
"""

Yes, like the "A" sound in "weird" or "ceiling".
http://jef.raskincenter.org/published/i_before_e.html
--
Aahz (aa**@pythoncraft.com) <* http://www.pythoncraft.com/

"I disrespectfully agree." --SJM
Mar 4 '07 #25

P: n/a
En Sat, 03 Mar 2007 19:55:16 -0300, Steven D'Aprano
<st***@REMOVE.THIS.cybersource.com.auescribió:
I personally don't see that pop has any advantage, especially since the
most useful example

while some_dict:
do_something_with(some_dict.pop())

doesn't work. Instead you have to write this:
For such constructs, one can use popitem:

while some_dict:
do_something_with(some_dict.popitem()[1])

The popitem method is older than pop. I don't like pop either.

--
Gabriel Genellina

Mar 6 '07 #26

This discussion thread is closed

Replies have been disabled for this discussion.