You can use the enumerate() function to loop over both the matrix values and give you indices:
newMatrix = [[0] * len(matrix) for _ in xrange(len(matrix[0]))]
for i, row in enumerate(matrix):
for j, value in enumerate(row):
newMatrix[j][i] = value
This outputs:
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
Because you are addressing rows and columns in the new matrix directly, you need to have initialized that new matrix with empty values first. The list comprehension on the first line of my example does this for you. It creates a new matrix that is (y, x) in size, given an input matrix of size (x, y).
Alternatively, you can avoid explicit looping altogether by (ab)using the zip function:
newMatrix = zip(*matrix)
which takes each row of matrix and groups each column in those rows into new rows.
In the generic case, python for constructs loop over sequences. The range() and xrange() functions can produce numerical sequences for you, these generate a number sequence in much the same way that a for loop in C or JavaScript would produce:
>>> for i in range(5):
>>> print i,
0 1 2 3 4
but the construct is far more powerful than the C-style for construct. In most such loops your goal is to provide indices into some sequence, the python construct bypasses the indices and goes straight to the values in the sequence instead.
zip(*matrix)