I was looking for flatmap
and found this question first. flatmap
is basically a generalization of what the original question asks for. If you are looking for a concise way of defining flatmap
for summable collections such as lists you can use
sum(map(f,xs),[])
It's only a little longer than just writing
flatmap(f,xs)
but also potentially less clear at first.
The sanest solution would be to have flatmap
as a basic function inside the programming language but as long as it is not, you can still define it using a better or more concrete name:
# `function` must turn the element type of `xs` into a summable type.
# `function` must be defined for arguments constructed without parameters.
def aggregate(function, xs):
return sum( map(function, xs), type(function( type(xs)() ))() )
# or only for lists
aggregate_list = lambda f,xs: sum(map(f,xs),[])
Strings are not summable unfortunately, it won't work for them.
You can do
assert( aggregate_list( lambda x: x * [x], [2,3,4] ) == [2,2,3,3,3,4,4,4,4] )
but you can't do
def get_index_in_alphabet(character):
return (ord(character) & ~0x20) - ord('A')
assert(aggregate( lambda x: get_index_in_alphabet(x) * x, "abcd") == "bccddd")
For strings, you need to use
aggregate_string = lambda f,s: "".join(map(f,s)) # looks almost like sum(map(f,s),"")
assert( aggregate_string( lambda x: get_index_in_alphabet(x) * x, "abcd" ) == "bccddd" )
It's obviously a mess, requiring different function names and even syntax for different types. Hopefully, Python's type system will be improved in the future.