I accidentally replied only to Steven - sorry! - this is what I said, with a typo corrected:
I much prefer this solution to any of the other things discussed so far. I wonder, though, would it be general enough to simply have this new '.' operator interact with __iter__, or would there have to be new magic methods like __veccall__, __vecgetattr__, etc? Would a single __vectorize__ magic method be enough?
For example, I would expect (1, 2, 3) .** 2 to evaluate as a tuple and [1, 2, 3] .** 2 to evaluate as a list, and some_generator() .** 2 to still be a generator.
If there were a __vectorize__(self, func) which returned the iterable result of applying func on each element of self:
class list: def __vectorize__(self, func): return [func(e) for e in self]
some_list .* other becomes some_list.__vectorize__(lambda e: e * 2) some_string..lower() becomes some_string.__vectorize__(str.lower) some_list..attr becomes some_list.__vectorize__(operator.__attrgetter__('attr'))
Perhaps there would be a better name for such a magic method, but I believe it would allow existing sequences to behave as one might expect, but not require each operator to require its own definition. I might also be over-complicating this, but I'm not sure how else to allow different sequences to give results of their same type.
On Thu, Jan 31, 2019 at 6:24 PM Steven D'Aprano email@example.com wrote:
On Thu, Jan 31, 2019 at 09:51:20AM -0800, Chris Barker via Python-ideas wrote:
I do a lot of numerical programming, and used to use MATLAB and now
lot. So I am very used to "vectorization" -- i.e. having operations that work on a whole collection of items at once.
You can imagine that for more complex expressions the "vectorized"
can make for much clearer and easier to parse code. Also much faster,
is what is usually talked about, but I think the readability is the
Julia has special "dot" vectorize operator that looks like this:
L .+ 1 # adds 1 to each item in L func.(L) # calls f on each item in L
The beauty of this is that you can apply it to any function or operator and the compiler will automatically vectorize it. The function doesn't have to be written to specifically support vectorization.
So what does this have to do with the topic at hand?
I know that when I'm used to working with numpy and then need to do some string processing or some such, I find myself missing this
-- if I want to do the same operation on a whole bunch of strings, why
need to write a loop or comprehension or map? that is:
[s.lower() for s in a_list_of_strings]
Using Julia syntax, that might become a_list_of_strings..lower(). If you don't like the double dot, perhaps str.lower.(a_list_of_strings) would be less ugly.
-- Steven _______________________________________________ Python-ideas mailing list Pythonfirstname.lastname@example.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/