2016-05-17 109 views
1

我的程序使用pyplot繪製形狀。我選擇以非常特別的方式創建形狀,因爲程序最終將解決this problem。因此,繪製形狀的信息包含在我命名爲big_shape的數據類型中。 big_shape是一個dicts列表,每個dict包含繪製一個1x1正方形所需的信息,我已經命名了一個unit_square。爲什麼我的函數在函數範圍之外改變它的參數?

在步驟我目前正在與掙扎,我創建了一個功能make_copies()應該做到以下幾點:

1. Iterate over each unit_square in a big_shape and run the transpose() function 
    -This should in turn create a new, transposed copy of the unit_square 
2. Compile the new unit_squares into a second big_shape 
3. Combine the new_big_shape with the original to make a third big_shape 
4. Return the third big shape so that everything can be plotted. 

這個問題似乎來自於轉置()函數。 I 期望函數獲取一個單位平方的輸入並將該單位平方的一個副本輸出到新位置,而不影響原始單位平方。但是,轉置功能似乎正在影響輸入單位正方形,使得它最終在轉置點中相互繪製原始圖像和轉置圖像。

你能幫我弄清楚爲什麼轉置()函數的行爲不如預期?

import matplotlib.pyplot as plt 


def make_unit_square(square_info): 
    ''' 
    A unit square is a 1x1 square. The square_info parameter is a two item list containing coordinates of the square's left top corner 
    point (index [0], given as a list or tuple) and its color (index [1]). make_unit_square returns a dict that will eventually be 
    the information input into a plt.Polygon(). 
    ''' 
    points = [square_info[0],[square_info[0][0]+1,square_info[0][1]],[square_info[0][0]+1,square_info[0][1]-1],[square_info[0][0],square_info[0][1]-1]] 
    return {'type': 'unit square','points': points, 'color': square_info[1]} 



def make_copies(big_shape): 
    ''' 
    A big_shape is a list of unit_squares. Thus, any function taking a parameter big_shape will iterate over the 
    composite unit squares. The make_copies function should iterate over each unit_square in a big_shape and run the 
    transpose() function, which should in turn create a new, transposed copy of the unit_square. These new unit_squares 
    are compiled into a new big_shape, which is then combined with the old big_shape and returned by the make_copies 
    function so that the two can eventually be plotted at once. 
    ''' 
    def transpose(unit_square,xdistance,ydistance): 
     new_unit_square = unit_square 
     new_points = [ [point[0] + xdistance, point[1] + ydistance] for point in unit_square['points']] 
     new_unit_square['points'] = new_points 
     return new_unit_square 


    #iterate over the big_shape, making a new, transposed copy of each of its composit unit_squares. THIS SHOULD LEAVE THE 
    #ORIGINAL BIG SHAPE UNCHANGED, BUT SOMETHING SEEMS TO GO WRONG. 
    new_big_shape = [transpose(x,0,10) for x in big_shape] 
    #combine the two big_shapes so they can be plotted at once 
    big_shape.extend(new_big_shape) 

    return big_shape 


plt.axes() 

#Below is the information for four unit_squares that will make up a big_shape 
big_shape_1_info = [ [[0,1],'green'], [[0,2], 'green'], [[1,2],'green'], [[1,1],'pink'] ] 
#Take that information and create a list of unit_squares, i.e. a big_shape. 
big_shape_1 = [make_unit_square(x) for x in big_shape_1_info] 
''' 
Here we make an even larger big_shape by making a transposed copy of big_shape_1 and saving both the original 
big_shape and its copy into one new big_shape. However, due to the bug, the unit_squares of big_shape_1 are 
erroneously changed in this step, so what we get is not the original big_shape and a transposed copy, but rather 
two transposed copies and no original. 
''' 
big_shape_2 = make_copies(big_shape_1) 
''' 
Next, we plot the new big_shape. This plotting is done by plotting each individual unit_square that makes up the big_shape. 
''' 
for unit_square in big_shape_2: 
    pol = plt.Polygon(unit_square['points'],color=unit_square['color']) 
    plt.gca().add_patch(pol) 
    print(unit_square) 



plt.axis('scaled') 
plt.show() 
+0

'new_unit_square = unit_square'將只複製引用,不復制對象。嘗試['copy()'](https://docs.python.org/2/library/copy.html)函數。 – Selcuk

回答

2

當你做什麼看起來是一項任務,

d = {1:[1,2,3]} 
D = d 

您只需將的新名稱添加到字典對象 - 同樣的推理適用於列表和其他可變對象 - 基礎是對象,現在您可以使用不同的名稱來引用同一對象。

無論哪個名字,你用它來修改一個對象,所有這些名字引用同一個對象

d[2] = 3 
D[3] = 4 
print d, D # --> {1:[1,2,3], 2:3, 3:4}, {1:[1,2,3], 2:3, 3:4} 

在您的使用情況下,你想字典的副本...

根據在字典的內容中,可以使用copy模塊中字典的.copy()方法或copy.deepcopy(...)函數。

的方法給你一個所謂的複製,因此複製是一個字典,但如果項目是可變,當你在原來的字典更改的項目,也該項目被修改

d = {1:[1,2,3]} 
D = d.copy() 
D[2] = '2' 
print d # --> {1:[1,2,3]} --- no new element in original 
D[1][0] = 0 
print d # --> {1:[0,2,3]} --- the original mutable content is modifed 

如果字典中的所有項目都不可變(例如,字符串,數字,元組),那麼.copy()就可以。

在另一方面,如果你有可變的項目(例如,列表,字典等),你想獨立副本,你想copy.deepcopy()

from copy import deepcopy 
d = {1:[1,2,3]} 
D = deepcopy(d) 
D[1][0]=0 
print d # --> {1:[1,2,3]} 

附: D = d.copy()等同於創建一個新的字典,D = dict(d):在這種情況下,您擁有的是淺拷貝。

1

Python是其中分配經過參考暗示的語言。所以,當你這樣做:

new_unit_square = unit_square 

你只是建立一個別名unit_square

嘗試以下操作:

import copy 
new_unit_square = copy.deepcopy(unit_square) 

點擊此處瞭解詳情:https://docs.python.org/2/library/copy.html

+0

「dict」類沒有'deepcopy()'方法。 – Selcuk

+1

對不起,你是對的。編輯 –

相關問題