为什么将此函数应用于未称为参数的变量? [英] Why is this function being applied to a variable which is not called as a parameter?

查看:53
本文介绍了为什么将此函数应用于未称为参数的变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在尝试编写一些代码时遇到麻烦.

I am having trouble with some code I am attempting to write.

我正在尝试获取一个坐标列表列表(表示3D形状的可能位置),并形成一个列表,该列表由原始列表中的所有元素以及另外旋转的原始列表中的元素组成,以便[x,y,z]坐标移动到也包括[z,x,y]和[y,z,x].

I am attempting to take a list of lists of coordinates (representing possible positions of a shape in 3D) and form a list which consists of all the elements in the original list and additionally the elements in the original list rotated so that the [x, y, z] coordinates are shifted to include [z, x, y] and [y, z, x] also.

我认为可以通过一个示例更好地说明这一点:

I think this is better illustrated with an example:

获取列表(代表2x2x1块的可能位置,因此为"two_by_two"):

Taking the list (representing the possible positions of a 2x2x1 block, hence "two_by_two"):

two_by_two = [
    [[-1, -1, 1],  [-1, -1, 0],  [-1, 0, 0],   [-1, 0, 1]],
    [[-1, -1, 0],  [-1, -1, -1], [-1, 0, -1],  [-1, 0, 0]]
    ...
]

(代表更相似坐标列表的椭圆)我试图形成完整列表:

(the ellipses representing more similar lists of coordinates) I am attempting to form the complete list:

two_by_two_comp = [
    [[-1, -1, 1],  [-1, -1, 0],  [-1, 0, 0],   [-1, 0, 1]],
    [[-1, -1, 0],  [-1, -1, -1], [-1, 0, -1],  [-1, 0, 0]]
    ...
    [[1, -1, -1],  [0, -1, -1],  [0, -1, 0],   [1, -1, 0]],
    [[0, -1, -1],  [-1, -1, -1], [-1, -1, 0],  [0, -1, 0]]
    ...
    [[-1, 1, -1],  [-1, 0, -1],  [0, 0, -1],   [0, 1, -1]],
    [[-1, 0, -1],  [-1, -1, -1], [0, -1, -1],  [0, 0, -1]]
    ...
]

我希望这很清楚.

我正在尝试通过使用将所有坐标都移动到two_by_two中的函数来实现这一点:

I am attempting to achieve this by using a function which shifts all of the coordinates in two_by_two:

# function to change [x, y, z] to [z, x, y]
def rotate_coordinates(parameter):
    coord_list = parameter[len(parameter) - 1]
    coordinates = coord_list[len(coord_list) - 1]

    z_coordinate = coordinates[2]
    coordinates.pop()
    coordinates.insert(0, z_coordinate)


# function to change list[x, y, z] to list[z, x, y]
def rotate_coord_list(parameter):
    coord_list = parameter[len(parameter) - 1]
    a = len(coord_list)
    while a > 0:
        coordinates = coord_list[len(coord_list) - 1]
        rotate_coordinates(parameter)
        coord_list.pop()
        coord_list.insert(0, coordinates)
        a = a - 1


# function to change list[list[x, y, z]] to list[list[z, x, y]]
def rotate_positions_list(parameter):
    b = len(parameter)
    while b > 0:
        coord_list = parameter[len(parameter) - 1]
        rotate_coord_list(parameter)
        parameter.pop()
        parameter.insert(0, coord_list)
        b = b - 1

在我看来,这在运行时是成功的:

This seems to me to be successful in that when I run:

print(two_by_two)
rotate_positions_list(two_by_two)
print(two_by_two)

它输出:

[[[-1, -1, 1], [-1, -1, 0],  [-1, 0, 0],  [-1, 0, 1]], 
 [[-1, -1, 0], [-1, -1, -1], [-1, 0, -1], [-1, 0, 0]]
...]

[[[1, -1, -1], [0, -1, -1],  [0, -1, 0],  [1, -1, 0]], 
 [[0, -1, -1], [-1, -1, -1], [-1, -1, 0], [0, -1, 0]]
...]

因此它按我的预期移动了所有坐标,当我尝试像这样开始创建two_by_two_comp时,就会出现问题:

And so it shifts all of the coordinates as I intended, the issue arises when I try to begin creating two_by_two_comp as so:

two_by_two_comp = []
two_by_two_comp.extend(two_by_two)
print(two_by_two_comp)

rotate_positions_list(two_by_two)
two_by_two_comp.extend(two_by_two)
print(two_by_two_comp)

哪个返回:

[[[-1, -1, 1], [-1, -1, 0],  [-1, 0, 0],  [-1, 0, 1]], 
 [[-1, -1, 0], [-1, -1, -1], [-1, 0, -1], [-1, 0, 0]]
...]

[[[1, -1, -1], [0, -1, -1],  [0, -1, 0],  [1, -1, 0]], 
 [[0, -1, -1], [-1, -1, -1], [-1, -1, 0], [0, -1, 0]],
... 
 [[1, -1, -1], [0, -1, -1],  [0, -1, 0],  [1, -1, 0]], 
 [[0, -1, -1], [-1, -1, -1], [-1, -1, 0], [0, -1, 0]]
...]

因此,我最终得到了相同的版本"与原来的移位版本相反,复制了two_by_two的副本,我不知道为什么我首先打印出的two_by_two_comp的部分会受到rotate_positons_list(two_by_two)函数的影响.

So I end up with the same "version" of two_by_two copied as opposed to the shifted and original version, and I have no idea why the section of two_by_two_comp which I print out first gets affected by the rotate_positons_list(two_by_two) function.

如果有人能消除我的困惑,我将非常感激.我将在下面的一小段中包含完整的脚本.

If anyone could clear up my confusion, I would be very grateful. I will include the full script in one piece below.

谢谢你,丹

two_by_two = [
    [[-1, -1, 1],  [-1, -1, 0],  [-1, 0, 0],   [-1, 0, 1]],
    [[-1, -1, 0],  [-1, -1, -1], [-1, 0, -1],  [-1, 0, 0]],
    [[-1, 0, 0],   [-1, 0, -1],  [-1, 1, -1],  [-1, 1, 0]],
    [[-1, 0, 1],   [-1, 0, 0],   [-1, 1, 0],   [-1, 1, 1]],

    [[0, -1, 1],   [0, -1, 0],   [0, 0, 0],    [0, 0, 1]],
    [[0, -1, 0],   [0, -1, -1],  [0, 0, -1],   [0, 0, 0]],
    [[0, 0, 0],    [0, 0, -1],   [0, 1, -1],   [0, 1, 0]],
    [[0, 0, 1],    [0, 0, 0],    [0, 1, 0],    [0, 1, 1]],

    [[1, -1, 1],   [1, -1, 0],   [1, 0, 0],    [1, 0, 1]],
    [[1, -1, 0],   [1, -1, -1],  [1, 0, -1],   [1, 0, 0]],
    [[1, 0, 0],    [1, 0, -1],   [1, 1, -1],   [1, 1, 0]],
    [[1, 0, 1],    [1, 0, 0],    [1, 1, 0],    [1, 1, 1]],
]


# function to change [x, y, z] to [z, x, y]
def rotate_coordinates(parameter):
    coord_list = parameter[len(parameter) - 1]
    coordinates = coord_list[len(coord_list) - 1]

    z_coordinate = coordinates[2]
    coordinates.pop()
    coordinates.insert(0, z_coordinate)


# function to change list[x, y, z] to list[z, x, y]
def rotate_coord_list(parameter):
    coord_list = parameter[len(parameter) - 1]
    a = len(coord_list)
    while a > 0:
        coordinates = coord_list[len(coord_list) - 1]
        rotate_coordinates(parameter)
        coord_list.pop()
        coord_list.insert(0, coordinates)
        a = a - 1


# function to change list[list[x, y, z]] to list[list[z, x, y]]
def rotate_positions_list(parameter):
    b = len(parameter)
    while b > 0:
        coord_list = parameter[len(parameter) - 1]
        rotate_coord_list(parameter)
        parameter.pop()
        parameter.insert(0, coord_list)
        b = b - 1


two_by_two_comp = []
two_by_two_comp.extend(two_by_two)
print(two_by_two_comp)

rotate_positions_list(two_by_two)
two_by_two_comp.extend(two_by_two)
print(two_by_two_comp)

推荐答案

您的问题在于深层副本和浅层副本之间的差异.根据文档

Your problem lies in the difference between deep copy and shallow copy. As per the docs

Python中的赋值语句不复制对象,它们在目标和对象之间创建绑定.对于可变或包含可变项的集合,有时需要一个副本,因此一个副本可以更改一个副本而无需更改另一个副本.

Assignment statements in Python do not copy objects, they create bindings between a target and an object. For collections that are mutable or contain mutable items, a copy is sometimes needed so one can change one copy without changing the other.

问题所在的行是:

two_by_two_comp.extend(two_by_two)

让我举一个使用两个列表 a b 的示例进行说明:

Let me illustrate with an example using two lists a and b:

a = [[2, 3, 4], [1, 2, 3]]
b = []
b.extend(a)

现在让我们说我在 a 内进行了一些修改:

Now let's say I modify something inside a:

a[0].append(3)
print(a)   #  [[2, 3, 4, 3], [1, 2, 3]]

一切都很好,但同时看看 b 发生了什么:

Everything is fine, but have a look at what happened to b in the meantime:

print(b)  #  [[2, 3, 4, 3], [1, 2, 3]]

它也被修改了.

要实现所需的功能,您需要创建 two_by_two 的深层副本,否则,您将只引用相同的内存地址.长话短说,而不是:

To achieve what you want, you need to create a deep copy of two_by_two otherwise you will just be referencing the same memory address. Long story short, instead of:

two_by_two_comp.extend(two_by_two)

您必须这样做:

two_by_two_comp.extend(copy.deepcopy(two_by_two))

别忘了在脚本顶部导入复制模块:

Don't forget to import the copy module at the top of your script:

import copy 

这篇关于为什么将此函数应用于未称为参数的变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆