代码之家  ›  专栏  ›  技术社区  ›  jokoon

python copy(),但列表似乎是通过copy传递的

  •  2
  • jokoon  · 技术社区  · 8 年前

    https://brilliant.org/wiki/recursive-backtracking/

    from itertools import *
    from copy import copy
    
    def is_distinct( list ):
        '''Auxiliary function to is_solved
        checks if all elements in a list are distinct
        (ignores 0s though)
        '''
        used = []
        for i in list:
            if i == 0:
                continue
            if i in used:
                return False
            used.append(i)
        return True
    
    
    def is_valid( brd ):
        '''Checks if a 3x3 mini-Sudoku is valid.'''
        for i in range(3):
            row = [brd[i][0],brd[i][1],brd[i][2]]
            if not is_distinct(row):
                return False
            col = [brd[0][i],brd[1][i],brd[2][i]]
            if not is_distinct(col):
                return False
        return True
    
    def solve( brd , empties = 9):
        '''
          Solves a mini-Sudoku
          brd is the board
          empty is the number of empty cells
        '''
    
        if empties == 0:
            #Base case
            return is_valid( brd )
        for row,col in product(range(3),repeat=2):
            #Run through every cell
            cell = brd[row][col]
            if cell != 0:
                #If its not empty jump
                continue
            brd2 = copy( brd )
            for test in [1,2,3]:
                brd2[row][col] = test
                if is_valid(brd2) and solve(brd2,empties-1):
                    return True
                #BackTrack
                brd2[row][col] = 0
        return False
    
    Board = [ [ 0 , 0 , 0 ],
              [ 1 , 0 , 0 ],
              [ 0 , 3 , 1 ] ]
    solve( Board , 9 - 3 )
    
    
    for row in Board:#Prints a solution
        print row      
    

    它返回正确的结果,即已求解的电路板。

    我不明白的是 solved() 递归函数修改了 Board brd ,它只写入 brd2 ,这是一个副本。

    然而,当列表在末尾打印时,它表明它已写入。

    所以我对这段代码有点困惑,我知道python函数通过引用传递列表,但这个示例显式使用 copy() . 我要么对复制感到困惑,要么遗漏了什么。

    2 回复  |  直到 8 年前
        1
  •  2
  •   MSeifert    8 年前

    copy.copy 制作一个 浅拷贝

    >>> a = [[1,2,3], [2,3,1], [3,1,2]]
    >>> b = copy(a)
    >>> b[0][0] = 100
    >>> a
    [[100, 2, 3], [2, 3, 1], [3, 1, 2]]
    >>> b 
    [[100, 2, 3], [2, 3, 1], [3, 1, 2]])
    

    在这种情况下,如果你根本不复制,它甚至可以工作,例如。

    brd2 = brd
    

    通常,您可以使用 deepcopy 无回溯或有回溯但无复制。但将复制和回溯结合起来似乎有点浪费。

        2
  •  0
  •   Community Mohan Dere    5 年前

    您正在创建 浅的 复制
    浅层复制就像您有一个对象并且它引用了其他对象一样。

    了解更多信息 HERE

    浅复制和深度复制之间的差异仅与复合对象(包含其他对象的对象,如列表或类实例)相关: