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
defget_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:
defget_something(keys):
defmy_itemgetter():
r = itemgetter(*keys)(d)
return (r,) iftype(r) isnottupleelse r
d = {
"a": 1,
"b": 2,
"c": 3
}
return my_itemgetter()
Post a Comment for "Python: Why Return-type Of Itemgetter Is Not Consistent"