自定义转置列表会在Python中混淆原始变量

时间:2013-08-08 18:01:33

标签: python-3.x transpose

我有这个功能应该转置它得到的列表。这有效,但由于某种原因,它也改变了原始矩阵:为什么?

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

输出:

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

我认为这无关紧要,但这里是转座功能:

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)

即使未对该变量调用该函数,Matrix变量如何也受影响?

1 个答案:

答案 0 :(得分:1)

当你这样做时

tMatrix = Matrix

实际上,您正在tMatrix对原始Matrix对象进行引用。因此,当您将transposer函数的输出分配回tMatrix时,您实际上正在更改原始Matrix对象本身。当你习惯了python时,这是一个非常常见的误解,例如你可以看到here(答案也值得一读)。

尝试阅读Python处理作业的方式,你会看到与其他语言的区别:

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

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

修改

要解决此问题,您可以通过copy operation复制传递给transpose的原始对象:

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)

正如旁注,您将元素视为字符串。如果他们应该是数字,你可以在没有" "的情况下输入它们。此外,如果您不需要使用自己的转置算法,则可以使用已经NumPymatrix transposition包。