2014-02-08 52 views
1

我正在寫一個小型的python腳本,打印出一行行,列表中的行本身就是一個字符串列表。這是函數的功能。它應該將列表作爲輸入並打印出漂亮的版本,而不用實際更改列表。我可以打印出正確的輸出。但經過仔細檢查,它也改變了原來的名單,雖然我在函數做的第一件事就是使用這種grid_copy = grid[:]Python - 功能改變的輸入列表,雖然我做了一個副本

問題使原始列表的副本:該腳本將任何''' '雖然我不修改列表

[['X', 'X', ''], ['', 'O', 'O'], ['O', 'X', '']]

到:

[X] [X] [ ] 

[ ] [O] [O] 

[O] [X] [ ] 

我不知道是什麼導致列表被改變,沒有我在哪裏引用原始列表,除非我在開​​始複製時。

我的代碼包含了幾個有用的註釋,我添加了這些註釋以便更容易理解我所做的事情。如果你運行代碼,那麼我也提供了一個測試用例。

def show_grid(grid): 
    """ 
    grid: list. A list of lines, where the lines are a list of strings 
    return: None 
     Prints the grid out in the classic 3x3 
    """ 
    grid_copy = grid[:] # make a copy so we do not want to actually change grid 
    len_grid = len(grid_copy) # I use this so much, might as well store it 

    # add whitespaces to make each single spot the same width 
    len_digits = len(str((len(grid_copy)**2))) # the number of chars wide the highest number is 
    # modification happens somewhere vvv 
    for line in range(len_grid): 
     for char in range(len_grid): 
      grid_copy[line][char] = str(grid_copy[line][char]).rjust(len_digits) # proper white spaces 

    # modification happens somewhere ^^^ 

    # add brackets, THIS IS NOT WHERE THE PROBLEM IS 
    for line in grid_copy: 
     print('[' + '] ['.join(line)+']\n') # print each symbol in a box 


# TESTING TESTING 
test_grid = [['X', 'X', ''], ['', 'O', 'O'], ['O', 'X', '']] 
print('test_grid before: {}'.format(test_grid)) 
show_grid(test_grid) # this should not modify test_grid, but it does 
print('test_grid after: {}'.format(test_grid)) 

OUTPUT:

test_grid before: [['X', 'X', ''], ['', 'O', 'O'], ['O', 'X', '']] 
[X] [X] [ ] 

[ ] [O] [O] 

[O] [X] [ ] 

test_grid after: [['X', 'X', ' '], [' ', 'O', 'O'], ['O', 'X', ' ']] 
+0

順便說一下,[鏈接](http://docs.python.org/2/library/copy.html)仍然有用,它應該始終是您的第一次訪問。 – keyser

回答

6

當你的目錄列表上寫grid_copy = grid[:],你只複製最上面的列表中,但不在名單本身的元素。這被稱爲淺拷貝深拷貝相對。你應該寫

grid_copy = [x[:] for x in grid] 

grid_copy = copy.deepcopy(grid) 
+0

所以我列表只是一個字符串列表而不是列表我的方法將工作? – Vader

+0

字符串列表應該做你想要的,因爲str是不可變的。 – dstromberg

+0

@Vader:使用l [:]來處理字符串列表是可以的,因爲字符串是不可變的(也就是說你不能在Python中修改字符串)。所以它不會複製一個字符串。 – hivert

3

使用源,盧克! (對不起,我不得不)

這是淺拷貝和深拷貝之間的區別。這在copy module的文檔中有詳細說明。淺拷貝僅處理第一級容器,並使用對包含對象的引用填充副本。而深拷貝也拷貝包含的對象。

+0

好吧,你有一個贊成來源評論 – Vader