On Wed, Jan 18, 2012 at 6:20 PM, Steven D'Aprano <steve+comp.lang.pyt...@pearwood.info> wrote: > On Wed, 18 Jan 2012 11:20:00 -0500, Devin Jeanpierre wrote: > Nobody likes to be told to brush their teeth, eat their vegetables or > clean their room. Then they grow up and learn that life is full of things > that you do because you have to, not because you want to.
I don't tell my coworkers to brush their teeth, clean their room, and eat their vegetables. You aren't his daddy. Also, DBAD principle always applies. "I'm just telling you the truth" is the defense of bullies. It's not about telling the truth, it's about helping people. Or at least, I assume it is. > That's just the way the zip operation works. If you can't specifically explain it, who are you to tell others it's trivial? > Because that's the nature of the Universe. If I asked why 1*-1 has to be -1, and not 1, you could just say "that's the nature of the universe", but that's just dodging the question. Statements like these are theorems that can be proven. The fact that they have been proven in the past does not magically make them obvious. (You might think so now, but I distinctly remember a lot of confusion in grade school when negative numbers were first introduced. For me that confusion was never properly resolved until much later.) The proof itself is the explanation, together with the explanations for why the definitions make sense, and why each step in the proof makes sense, recursively until the person who doesn't know why this should be true is satisfied, or until the person is lost [in which case, need to do something more bottom-up; you can't teach somebody integration if they don't get multiplication]. If possible, intuitive analogies should be used. (Math is specifically designed around intuition as much as feasible.) In the case of 1*-1 = -1, the explanation is that the definition of "1" is that 1 * x = x, even if x is -1 [*] (this can be worded less algebraically, since whoever asks you this is probably 7 years old). Then one might ask, "well, why is that?", and then we must result to the intuitive explanation of what "one" is, and how we extend that to negative numbers (e.g. "take one step back" versus "one step forward"; "one backward step", etc.). The point is that of _course_ it's the nature of the universe. Every mathematical theorem follows from the definitions. That doesn't mean it's simple, and that doesn't mean it can't be explained. As a matter of fact it can be explained: I gave the explanation that made me "get it". I'm sure there are other ways of wording the idea, but "that's just the way the universe is" doesn't do anything for anyone except make one confused person feel a little worse. > The only complication is that you can't just pass the result of zip back > to zip directly, you have to use the unpack operator * to split the > result "one sequence of N subsequences" into N separate arguments. > > But apart from that complication, if you zip a bunch of sequences, then > zip it again, you get back the original order. You describe that as > taking the transpose of a matrix, which is correct, but that just puts a > name to it, it doesn't explain *why* taking the transpose twice gives you > the original matrix. I did more than just say "nyer it's the transpose", I explained what a transpose is and why it is that transpose is its own inverse. I think you're right in thinking my explanation was too short, though. Short version I already stated: the reason taking the transpose twice results in the original matrix is because exchanges rows and columns -- the columns of the transpose are the rows of the original. Exchanging twice leaves you with the original (the comparison with reverse is appropriate). Call the transpose of A t(*A). Each row of t(*t(*A)) is a column of t(*A), and each column of t(*A) is a row of A. so clearly every row of t(*t(*A)) is a row of A. I assert that there are also the same number of rows by the definition of the transpose (it only swaps, doesn't delete), so t(*t(*A)) is the same as A! [All the rows are the same, and there are the same number of rows <--> they are the same] At this point I have to explain that t = zip. We could do this by definition (ignoring that Python uses no such words), or we could do this by explaining how the docs for zip describe transpose, or we could say "compare it with transpose on several example matrices. The second option turns out to pan out better than expected: here is how Python defines zip: This function returns a list of tuples, where the i-th tuple contains the i-th element from each of the argument sequences or iterables. This is how wikipedia defines the transpose: Formally, the (i,j) element of A-Transpose is the (j,i) element of A. Wikipedia adds the "j" to explain that the elements in the rows are in the same order as the respective column in the original matrix. This is also implied in the zip definition, but not made explicitly clear. I assert that these are equivalent for matrices based on the above [zip includes an additional sentence addressing non-matrices], and based on perhaps a few manual experiments to verify that order is kept by zip(). The only issue left now is that you can pass things that aren't matrices into zip. zip has its own way of turning them into matrices, which results in information being cut out -- specifically, if we have a nested-sequence that doesn't really look like a rectangle (some rows are longer than others), it cuts it short to force it into the shape of a rectangle, treats this nested list as a matrix, returns the transpose of the matrix. So zip(*x) is really only almost its own inverse -- it's precisely its own inverse for matrices. -- Devin -- http://mail.python.org/mailman/listinfo/python-list