1

I have this function that should transpose the list it gets. This works, but for some reason it alters the original matrix as well: why?

Matrix = [["1"], ["1","2"], ["1","2","3","4"], []]

def test():
    global Matrix # same happens when global or not
    tMatrix = Matrix
    print(tMatrix) # 1
    tMatrix = transposer(Matrix)
    print(tMatrix) # 2
    print(Matrix) # 3

Output:

[['1'], ['1', '2'], ['1', '2', '3', '4'], []]   # 1
[['1', '1', '1'], ['2', '2'], ['3'], ['4']]     # 2
[[], [], [], []]                                # 3

I think it should not matter, but here is the transposer function:

def transposer(m):
    tm = []
    maxi = 0
    for i in range(0, len(m)):
        maxi = max(maxi, len(m[i]))
    for z in range(0, maxi):
        row = []
        for j in range(0, len(m)): 
            try:
                row.append(m[j].pop(0))
            except:
                pass
        tm.append(row)
    return(tm)

How is it possible that the Matrix variable is also affected even though the function is not called on that variable?

4

1 回答 1

1

When you do

tMatrix = Matrix

in reality you are making tMatrix a reference to the original Matrix object. So, when you assign the output of the transposer function back to tMatrix you are really changing the original Matrix object itself. This is a very common misunderstanding when you're getting used to python, like you can see here, for example (the answer is worth reading too).

Try to read something on the way Python treats assignments and you'll see the difference from other languages:

http://learnpython.pbworks.com/w/page/15956522/Assignment

http://anh.cs.luc.edu/python/hands-on/3.1/handsonHtml/variables.html

EDIT:

To solve the problem, you can make a copy of the original object passed to transpose through a copy operation:

def transposer(n):
    m = copy.copy(n)
    tm = []
    maxi = 0
    for i in range(0, len(m)):
        maxi = max(maxi, len(m[i]))
        print i, maxi
    for z in range(0, maxi):
        row = []
        for j in range(0, len(m)): 
            try:
                row.append(m[j].pop(0))
            except:
                pass
        tm.append(row)
    return(tm)

Just as a sidenote, you're treating your elements as strings. If they were supposed to be numeric you can just enter them without the " ". Also, if you don't need to use your own transposing algorithm, you can just use the NumPy package, which already does matrix transposition.

于 2013-08-08T18:06:01.110 回答