When I started with Python, there were not yet NumPy or SymPy. We used to do research in MatLab, rapid prototyping in Delphi and, believe me or not, symbolic computation in Prolog. Python was something like a nicer Perl, not really popular with the researchers. But it was fun to write things in.
So we did. I choose to implement a couple of experiments for my thesis in Python, and I had to bring a bit of linear algebra with it. I started with writing some Pascal-style loop over loop routines, which was not very exciting, but the more I got into the Python, the more pleasurable it got to become. At some point, I felt that there is something more in the language than loops over loops and started researching the language instead of my original topic. Probably, the best wrong decision I ever took.
Python is famous for its gentle learning curve, but this may very well fire back. You can do Pascal in Python, you can do C++ in Python, you can do Lisp in Python, but you really get the leverage only by doing Python in Python. Yet it is too easy to live with the very basic knowledge. You may be missing all the awesome parts and still feel fine about it.
This article is supposed to show you how powerful Python is at its core. To illustrate this, I chose the domain of linear algebra. Of course, Python has very decent packages for it so you probably wouldn't have to reimplement anything described here. However, I only chose linear algebra due to my lack of imagination. The syntax that allows us to put so much sense in so little code is universal.
Disclaimer: for the sake of readability not all the code samples are actually written in a single line each. It is, of course, possible since neither of them contains Python control structures that rely on indentation. All the indentation in the examples is entirely voluntaristic.
List comprehensions are the staple of Python one-liners. It is a special syntax that describes list transformations. Let's say we want to multiply a vector by a scalar. In Pascal-ish Python this would be something like this.
def scaled(A, x): B = list() for i in range(len(A)): B.append( A[i] * x ) return B
Which is fine. This style has its benefits too, for example, you always have a line to put a breakpoint to. But this is overly verbose. In Python, you can simply do this.
def scaled(A, x): return [ai*x for ai in A]
And it works like that.
List comprehension [1.0, 4.0, 3.0] * 2.0 [, ... Step 1 [1.0, 4.0, 3.0] * 2.0 [2.0, ... Step 2 [1.0, 4.0, 3.0] * 2.0 [2.0, 8.0, ... Step 3 [1.0, 4.0, 3.0] * 2.0 [2.0, 8.0, 6.0]
Reactivate Joy by Self-teching with You