I think it would be great to add a few more spoons of syntactic sugar for working with lists and other indexable objects. The idea is pretty simple to implement and doesn’t require major changes.
Currently, you might write:
myval = mylist[1] if len(mylist) > 1 else None
# or
try:
myval = mylist[1]
except IndexError:
myval = None
But wouldn’t it be cleaner and simpler to have:
myval = mylist.get(1)
A lot of people on Stack Overflow are asking about this functionality, and I agree it’s not an uncommon case. Maybe it’s time to take a second look at this idea? What do you think?
Are there many use cases after a list.get call that don’t require a subsequent test such as: if myval is None (or if myval =='Sentinel' if None is in the list)?
Case when some APIs return an empty list or a list with exactly one element, or if you need only the first element because the target structure doesn’t have a field for more than one:
A case with some libraries that return only batches when you need only the first element: For example, face detection algorithms might return a list of detected rectangles, but you might only care about the first one. (This is not the best example because, in the case of face detection, you might want to process 2+ detections separately; however, I can’t think of a better one at the moment.)
detected_faces = some_cv_lib.detect_faces('foo.jpg')
first_face = detected_faces[0] if detected_faces else None
Can’t provide enough examples because of 2 links limitation. There’s 5 links in the original discussion. And I can find few dozens more with google queries like ‘safe get method for list python’.
I’m a big fan of duck typing. I don’t use any type-checking tools and would never want to get into the kinds of messes that I see others create with them; but I sometimes annotate my interfaces as documentation, and use collections.abc typenames to do so. If I write something that conceptually expects an immutable mapping of integers to whatever, I’d like to be able to accept a list - or a tuple - transparently. That kind of thing is a big part of why I use Python. Having a .get method would help support my style of programming.
This seems like much more of a “mess” than using type checking and having guarantees about what you can and can’t pass, and what a function accepting something can and can’t do.
That said, you can just pass dict(enumerate(x)) to convert a list[T] to a Mapping[int, T].
It doesn’t happen very often to me, but it does happen consistently. From time to time I am doing something and I find myself in a place where it is somewhat obvious that get of list would be the “one best way to do it”.
The last one (few minutes ago):
if args and args[-1] is VOID:
raise
# Alt
if args.get(-1, None) is VOID:
raise
Over the last year I have encountered around 4-5 such uncorrelated occurrences.
This is not very pleasant for inline usage:
if ([myval] = mylist[1:2] or [None])[0] is None:
...
I’ve written my own version […] but then struggled to find a good use for it. It seems like it ought to
be useful, but in practice I found that it was only covering up bugs in my code.
This is an extremely good test of an idea. If you write your own version, and then find that you don’t use it (because it’s not worth the effort to import it, or because what you need isn’t quite the same as the version you wrote, or for some other reason) then maybe the idea wasn’t as good in practice as you hoped it would be.
This can be a good test, but don’t think this is decisive factor for all cases (not even majority in my case).
I don’t use a lot of what I could implement in python due to couple of reasons:
a) Performance
b) I try to use constructs provided by standard library as much as possible. Otherwise, I have a lot of code that becomes obsolete once a good solution becomes available in standard library.
E.g. my above example:
if args and args[-1] is VOID:
raise
# Alt
if args.get(-1, None) is VOID:
raise
And there are a lot of python features that if were not implemented I would use next best method in standard library instead of implementing my own.
E.g. dict.get
Would I write my own function?
def dict_get(...):
...
a = dict_get(d, default)
Ow would I just?
a = d[k] if k in d else default
Does it mean, that dict.get is unnecessary method?