2014-02-08 24 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