2013-05-27 24 views
1

我將列表的副本傳遞給一個函數,出於某種原因原始列表發生了變化。我嘗試了所有可能的方法,這完全不合邏輯,或者我做了一些非常錯誤的事情。爲什麼列表沒有理由變化?

maze="""XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 
XXX   XXXXXXXXXXXXXXXXXXXXX EXX 
XXXXXXXXXXXXXX XXX   XXXX  XXX 
XX XX   XXX XXXXXXX XXXX XXXXXXX 
XX XX XXXXXXXXX XX XXXXXXX XXXX XXXXXXX 
XX XX XXXXXXX XXXXX XXXXXXX XXXX XXXXXXX 
XX XX XXXX XXXXX XXXXX    XX 
XX XX XXXX XX XXXXX XXX XXXXXXXXXXXXXX 
XX XX XXXX XX XXXXXXX XXX  XXXX XX 
XX XX  XX  XXX XXXXXXX XXXX XX XX 
XX XXXXXXXXXX XXX XXX XXXXXXX  XXXXX 
XX  XXXXX XXX XXXXXX  XXXX XXXXX 
XXXX XX XXXXX XXX XX  XXXX XXXX XXX 
XXXX XX XXXXX XXX XX XXXXXXXX XXXXXX XXX 
XX XX XXX XXX XX XXXXX  XXXX XXX 
XXXX XX  XXXXX XXXXX XXXXXXX XXXXX 
XXXX XXXXXXXXXXXXXXXXXXXXX XXXXXXX XXX 
XXXX    XXX  XXXXX XXX 
XXXXXXXXXXXXXXXX XXXXXX XXXXXX XXXXX XXX 
XXX    XXXXXX XXXXXX XXXXX XXX 
XXX XXXXXXXXXXXXXXXXX XX  XXXXX XX 
XXX    XX XX XXXX XXXXXXXXXX XX 
XS XXXXXXXX XXXXX XXXX   XX 
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX""" 
grid=maze.split("\n") 
for x in xrange(len(grid)): 
    grid[x]=list(grid[x]) 
row=len(grid) 
col=len(grid[0]) 
def check(maze,x,z,row,col): 
    lim=0 
    if z+1<col and maze[x][z+1]=="X": 
     lim+=1 
    if x+1<row and maze[x+1][z]=="X": 
     lim+=1 
    if z-1>=0 and maze[x][z-1]=="X": 
     lim+=1 
    if x-1>=0 and maze[x-1][z]=="X": 
     lim+=1 
    return lim 
def get_pos(grida,row,col): 
    for l in xrange(100): 
     for x in xrange(len(grida)): 
      for z in xrange(len(grida[x])): 
       if check(grida,x,z,row,col)>=3 and grida[x][z]!="E" and grida[x][z]!="S": 
        grida[x][z]="X" 
       else: 
        continue 
    return grida 
grid_temp=grid[:] 
print grid 
grid_2=get_pos(grid_temp,row,col) 
print grid 

我想知道爲什麼網格實際上在變化。

+0

是嗎?提出以「爲什麼」開頭的問題不是一個好主意。首先請確定,該列表實際上*是*改變*沒有理由*。 – 2013-05-27 14:05:44

+0

@LutzHorn你看,我想知道原因,如果真的有一個。我似乎無法找到它。 grid_temp =電網[:] 打印電網 grid_2 = get_pos(grid_temp,行,列) 印刷網 這只是其中有什麼關係呢 –

回答

10

您的網格變量是一個二維數組,即列表的列表。當您做grid[:]時,您正在製作一個新的列表清單,但這些元素本身仍然是對同一迷宮行的引用。您想要進行深層複製,例如來自copy模塊的deepcopy功能。

+0

咄較短的答案被更快地編寫功能之後改變,不是嗎? :P –

+0

非常感謝mate.This工作perfect.Well我想我還有很多東西需要學習,但我從來不知道,這樣的感謝:d –

1

簡單的解決方案,而不是使用特別複製copy模塊:

import copy 
foo = copy.deepcopy(bar) 

要回答你的問題,我覺得爲什麼歸結爲你的代碼以下位:

grida[x][y] = ... 

雖然您的[:]副本只複製一層深度,分配深度爲兩層。

+0

謝謝,但我試過[:] [:]我remember.It還是沒有work.Anyways非常感謝這一點以及:p –

+1

[:] [:]複製一層深兩次 –

0

你,我的朋友,在命名空間遇到問題。 嘗試new_array = old_array [:]。 這會導致數組中的切片,但是因爲在冒號前後沒有任何數字,所以不會切斷任何數據,但仍會強制重複數組。

命名和結合

名稱參考對象。名稱是通過名稱綁定 操作引入的。節目文本中名稱的每次出現指的是在包含該用途的最內層功能塊 中建立的那個名稱的綁定

A 是作爲 單元執行的一段Python程序文本。以下是塊:模塊,函數體和類 的定義。交互式輸入的每個命令都是一個塊。腳本 文件(作爲解釋程序的標準輸入文件或作爲解釋程序的命令行參數指定的 )是代碼塊。 A 腳本命令(在解釋器命令行 上使用'-c'選項指定的命令)是一個代碼塊。字符串參數將 傳遞給內置函數「eval()」,「exec()」是一個代碼塊。

代碼塊在執行框架中執行。一個幀包含 一些管理信息(用於調試)並確定 在代碼塊的執行完成後 執行後繼續執行的位置和方式。

A 範圍定義塊內名稱的可見性。如果在塊中定義了本地變量 ,則其範圍包括該塊。如果 定義發生在功能塊中,則範圍擴展到包含在定義範圍內的任何塊 ,除非包含的塊爲名稱引入了不同的綁定 。在 類塊中定義的名稱範圍僅限於類塊;它不會擴展到 方法的代碼塊 - 這包括理解和生成器 表達式,因爲它們是使用函數作用域實現的。這 意味着以下將失敗:

A類: 一個= 42 B =列表(A + I對於i在範圍(10))

當一個名稱以代碼塊中使用,它使用最近的 封閉範圍來解決。代碼塊 可見的所有這些範圍的集合稱爲塊的環境

如果一個名稱被綁定在一個塊中,它是該塊的局部變量, ,除非聲明爲「nonlocal」。如果名稱在模塊 級別綁定,則它是一個全局變量。 (模塊代碼 的變量是本地和全局的。)如果在代碼塊 中使用變量,但未在此處定義變量,則該變量爲自由變量

如果找不到名稱,則會引發「NameError」異常。 如果名稱引用未綁定的局部變量,則會引發「UnboundLocalError」異常。 「UnboundLocalError」是「NameError」的子類 。

以下構建體結合的名稱:函數的形式參數, 「導入」語句,類和函數定義(這些結合在定義塊中 類或函數名),並且是 標識符如果在存在目標賦值「,」for循環頭「,或在 之後」as「在」with「語句或」except「子句中。 「from ... import *」形式的「import」語句 將綁定導入模塊中定義的所有名稱,但以下劃線開頭的名稱除外。此表格 只能在模塊級別使用。

發生在「del」語句中的目標也被認爲綁定爲 (儘管實際的語義是解除綁定名稱)。

每個分配或導入語句發生在由 類或函數定義或模塊級別(頂層 代碼塊)定義的塊中。

如果名稱綁定操作發生在代碼塊內的任何位置,則該塊內名稱的所有使用將被視爲對當前塊的引用。當在綁定之前在 塊中使用名稱時,這可能會導致錯誤。這條規則很微妙。 Python缺少 聲明並允許在代碼塊內的任何地方發生名稱綁定操作 。代碼塊的局部變量可以是 ,通過掃描名稱綁定 操作的塊的全部文本來確定。

如果「全局」語句出現在塊中,則在語句中指定的名稱 的所有用法引用該名稱在 頂級名稱空間中的綁定。名稱在頂級命名空間由 解決搜索全局命名空間,即包含代碼塊的模塊 的命名空間,以及內建的命名空間,名稱空間中的模塊「內建」的 。首先搜索全局名稱空間。如果 在那裏找不到該名稱,則搜索builtins名稱空間。全局聲明必須在名稱的所有用法之前。

一個代碼塊 的執行相關的內建名字空間實際上是通過查找名字在其全球 命名空間「內建」發現;這應該是一個字典或一個模塊(在後一種情況下,使用該模塊的字典 )。默認情況下,當「主要」 模塊中,「內建」是內置模塊「建宏」;當任何其它 模塊中,「建宏」是用於 「內建」模塊本身的字典的別名。 「內建」可以被設置爲用戶創建的字典 創建受限執行的弱形式。

CPython的實現細節:用戶不應觸摸 「內建」;它嚴格地是一個實現細節。用戶 想要覆蓋builtins命名空間中的值應該「導入」 「builtins」模塊並適當修改其屬性。

爲一個模塊的名稱空間是自動創建的第一次 模塊被導入。腳本的主要模塊始終被稱爲 「main」。

「全局」語句與在同一個塊中的名稱綁定操作 具有相同的範圍。如果自由變量 最近的封閉範圍包含全局語句,則自由變量將被視爲全局變量。

一個類的定義是,可以使用和定義 名的可執行語句。這些引用遵循名稱解析的正常規則。 類定義的名稱空間成爲該類的屬性字典 。在類範圍中定義的名稱在 方法中不可見。

與動態功能

互動


有以下幾種情況:其中在結合包含自由變量嵌套範圍使用 時Python語句是非法的。

如果在封閉範圍內引用一個變量,則 是非法的刪除名稱。錯誤將在編譯時報告。

如果進口---的外卡形式「進口*」 ---是在 功能使用,功能包含或者是免費 變量嵌套塊,編譯器將拋出一個「SyntaxError錯誤」。

的「的eval()」和「EXEC()」函數沒有獲得解決的名字全 環境。名稱可以在本地 和調用者的全局名稱空間中解析。自由變量在最近的封閉名稱空間中不解析爲 ,而是在全局名稱空間中解析。 [1] 「exec()」和「eval()」函數具有可選參數,以覆蓋全局和本地命名空間,即 。如果只指定了一個名稱空間 ,則它用於兩者。

相關幫助主題:global,nonlocal,ASSIGNMENT,DELETION,DYNAMICFEATURES

相關問題