I dislike programming patterns that use looping variables just because 'this is the standard way to do it'. Even functional iteration is in some cases redundant.
Some examples in python:
Do a map on list:
[fn(var) for var in list]
Here var is pretty redundant. Map is more concise:
map(fn, list)
But, when it comes to taking some attribute/calling a function on every element of a list, things get ugly for map,
map(lambda var: var.attribute, list)
but stay about the same for the list comprehension:
[var.attribute for var in list]
Something as concise as the first expression of map for attributes would be a welcome. Expressing it in python:
mapper(list).attribute
'.' is used to take the attribute because it's shorter than using a string attribute and is more intuitive.
A possible implementation:
class mapper(list):
def __getattr__(self, attr):
list.__init__(self, [getattr(x, attr) for x in self])
return self
return self
def __call__(self, *args, **kws):
list.__init__(self, [x(*args, **kws) for x in self])
return self
return self
Here you cannot use attributes that are methods in the list class.
The advantage can be noticed for accessing attributes that don't have a functional accesor (ie lambda x: x.attribute).
Examples of use:
mapper("aBcD").lower()
==> ['a', 'b', 'c', 'd']
class a: a = 1
mapper([a() for x in range(3)]).a
==> [1, 1, 1]
==> ['a', 'b', 'c', 'd']
class a: a = 1
mapper([a() for x in range(3)]).a
==> [1, 1, 1]
Other uses (call every function in a list):
mapper([lambda:1,lambda:2])()
==> [1, 2]
mapper("ab ac bc".split()).replace('a','x').capitalize()
==> ['Xb', 'Xc', 'Bc']
==> [1, 2]
mapper("ab ac bc".split()).replace('a','x').capitalize()
==> ['Xb', 'Xc', 'Bc']
1 comment:
Well said.
Post a Comment