2

Is there a way to do the following in python with a builtin, or does it require a user function?

l = [1,]
l.pop(0)
# 1
l.pop(0)
# IndexError: pop from empty list <-- I want it to return None

In other words, something for the following:

popsafe = lambda l: l.pop(0) if l else None
David542
  • 104,438
  • 178
  • 489
  • 842
  • 1
    `list.pop()` does not take in defaults https://docs.python.org/3/tutorial/datastructures.html – drum Mar 31 '21 at 01:14
  • @drumb -- right I'm wondering if there is some other builtin such as a stack ds. – David542 Mar 31 '21 at 01:14
  • It will come down to implementing your own – drum Mar 31 '21 at 01:15
  • 3
    *Is there a way to do the following in python with a builtin* - No - there isn't. You could write it as `(l or [None]).pop(0)` but that's fairly meh... – Jon Clements Mar 31 '21 at 01:15
  • 3
    You can also implement your own `list` class using https://docs.python.org/3/library/collections.html#collections.UserList but it's probably not worth it. – Selcuk Mar 31 '21 at 01:17
  • 4
    If you're repeatedly popping from index 0 (the "left" side of the list) then you should consider using a `deque` instead. list pops are only cheap from the right end. – wim Mar 31 '21 at 01:31
  • @wim thanks for pointing that out...I didn't even realize that at first until you said that. – David542 Mar 31 '21 at 01:33
  • 1
    Sidenotes: 1) [`l` is a bad variable name since it looks like `1` and `I`](https://www.python.org/dev/peps/pep-0008/#names-to-avoid); you could use `L` instead. 2) [Named lambdas are bad practice](/q/38381556/4518341). Use a `def` instead. – wjandrea Mar 31 '21 at 01:33
  • @wjandrea thanks for the tip. If interested in taking a look: https://codereview.stackexchange.com/questions/258908/lisp-expression-parser – David542 Mar 31 '21 at 01:48

1 Answers1

1
import contextlib

def pop_with_default(l, position=1, default=None):
    with contextlib.suppress(IndexError):
        return l.pop(position)
    return default
DevLounge
  • 8,313
  • 3
  • 31
  • 44
  • 1
    I didn't downvote, but the OP would like it to return `None` – juanpa.arrivillaga Mar 31 '21 at 01:36
  • 1
    Then there should be a variable assignment in his code when he pops! – DevLounge Mar 31 '21 at 01:38
  • @DevLounge I didn't downvote, actually I'm the one who upvoted your answer. Even if it's not a perfect answer, I appreciate the response and learned about the contextlib which I had never used before. Thanks. – David542 Mar 31 '21 at 01:43
  • 2
    May I suggest default value for `position=-1` for consistency with `list.pop`. (I often see people needlessly popping from the start), whereas popping from the end is faster – Mikael Öhman Mar 31 '21 at 01:50
  • 2
    Maybe downvoted because it's a code only answer with no explanation? It did come up in review, flagged as low-quality for its length and content. – Robert Mar 31 '21 at 02:48
  • 1
    This is about 400% slower than the simple conditional which the OP already had in the question, and it's about 900% slower in the case of an empty list. It's also more code, and less readable than just using a simple if-statement. Why would you do it like this? – wim Mar 31 '21 at 03:51
  • @Robert not really, no. this is pretty self-evident to anyone moderately familiar with Python and having lots of verbiage around contextlib.suppress would likely leave a noob more confused than enlightened. – JL Peyret Mar 31 '21 at 03:51