Python: Why Return-type Of Itemgetter Is Not Consistent
Solution 1:
Is there some other built-in option if I always want to return a tuple/list given the keys?
just use a comprehension:
[d[k] for k in keys]
In context:
from operator import itemgetter
def get_something(keys):
d = {
"a": 1,
"b": 2,
"c": 3
}
return [d[k] for k in keys]
print(get_something(["a", "b"]))
#[1, 2]
print(get_something(["a"]))
#[1]
print(get_something([]))
#[]
Solution 2:
Part of your confusion comes from the fact that your get_something()
func takes a single argument (expected to be an iterable) and unpacks it when passing it to itemgetter()
. This results in the return value of get_something()
not being "symetric" with it's arguments.
If you defined get_something()
to use varargs instead (as itemgetter()
does) :
def get_something(*keys):
d = {
"a": 1,
"b": 2,
"c": 3
}
return itemgetter(*keys)(d)
the return values would be more consistant with the arguments, ie:
# ask for 3 keys, get 3 values:
>>> get_something("a", "b", "c")
(1, 2, 3)
# ask for 2 keys, get 2 values:
>>> get_something("a", "b")
(1, 2)
# ask for one key, get 1 value
>>> get_something("a")
1
# all of this with tuple unpacking in mind:
a, b = get_something("a", "b")
a = get_something("a")
Now the point is that few people would bother using itemgetter()
to implement your get_something
function - itemgetter
has mainly been designed to be used as a callback for sorted()
and like functions / methods (where it's current behaviour makes sense), and get_something
would more canonically be implemented with a list expression ie:
def get_something(keys):
d = {
"a": 1,
"b": 2,
"c": 3
}
return [d[k] for k in keys]
which would take an iterable and return a (possibly empty) list.
Solution 3:
This behavior is documented in the docs (emphasis is mine):
Return a callable object that fetches item from its operand using the operand’s
__getitem__()
method. If multiple items are specified, returns a tuple of lookup values
itemgetter
does not decide the return type, it is the operand's __getitem__()
method.
Wouldn't it be easier/better
"better" is subjective. You can always wrap itemgetter
:
def get_something(keys):
def my_itemgetter():
r = itemgetter(*keys)(d)
return (r,) if type(r) is not tuple else r
d = {
"a": 1,
"b": 2,
"c": 3
}
return my_itemgetter()
Post a Comment for "Python: Why Return-type Of Itemgetter Is Not Consistent"