【问题标题】:Why is taking a slice of a list which is assigned to another list not changing the original?为什么将分配给另一个列表的列表切片不改变原始列表?
【发布时间】:2020-02-18 11:18:17
【问题描述】:

我有一个表示数学张量的类。类中的张量存储为单个列表,而不是另一个列表中的列表。这意味着[[1, 2, 3], [4, 5, 6]] 将存储为[1, 2, 3, 4, 5, 6]

我已经创建了一个__setitem__() 函数和一个函数来处理这个张量的切片,而它是单个列表格式。例如,对于上述列表,slice(1, None, None) 将变为 slice(3, None, None)。但是,当我为这个切片分配一个新值时,原始张量不会更新。

这是简化代码的样子

class Tensor:
    def __init__(self, tensor):
        self.tensor = tensor # Here I would flatten it, but for now imagine it's already flattened.

    def __setitem__(self, slices, value):
        slices = [slices] 
        temp_tensor = self.tensor # any changes to temp_tensor should also change self.tensor.

        for s in slices: # Here I would call self.slices_to_index(), but this is to keep the code simple.
            temp_tensor = temp_tensor[slice]

        temp_tensor = value # In my mind, this should have also changed self.tensor, but it hasn't.

也许我只是愚蠢,不明白为什么这不起作用。也许我的实际问题不仅仅是“为什么这不起作用?”但还有“有没有更好的方法来做到这一点?”。感谢您能给我的任何帮助。

注意事项:

列表的每个“维度”必须具有相同的形状,因此不允许使用[[1, 2, 3], [4, 5]]

此代码已大大简化,因为还有许多其他帮助函数和类似的东西。

__init__() 中,我会将列表展平,但正如我刚才所说,为了简单起见,我将其与self.slice_to_index() 一起省略了。

【问题讨论】:

    标签: python-3.x list slice mutable


    【解决方案1】:

    您不应将 python 变量视为c++java 中的变量。将它们视为您放置在价值观上的标签。检查这个例子:

    >>> l = []
    >>> l.append
    <built-in method append of list object at 0x7fbb0d40cf88>
    >>> l.append(10)
    >>> l
    [10]
    >>> ll = l
    >>> ll.append(10)
    >>> l
    [10, 10]
    >>> ll
    [10, 10]
    >>> ll = ["foo"]
    >>> l
    [10, 10]
    

    如您所见,ll 变量首先指向同一个 l 列表,但后来我们只是让它指向另一个列表。修改后面的ll不会修改l指向的原始列表。

    因此,如果您希望 self.tensor 指向一个新值,就这样做吧:

    class Tensor:
        def __init__(self, tensor):
            self.tensor = tensor # Here I would flatten it, but for now imagine it's already flattened.
    
        def __setitem__(self, slices, value):
            slices = [slices] 
            temp_tensor = self.tensor # any changes to the list pointed by temp_tensor will be reflected in self.tensor since it is the same list
    
            for s in slices: 
                temp_tensor = temp_tensor[slice]
    
            self.tensor = value
    

    【讨论】:

    • 这是有道理的,所以我现在可以明白为什么我的原始功能不起作用了。我会试试你的方法。
    猜你喜欢
    • 2017-10-29
    • 2012-06-24
    • 1970-01-01
    • 2021-04-06
    • 2017-07-11
    • 1970-01-01
    • 2021-07-21
    • 2017-11-02
    • 1970-01-01
    相关资源
    最近更新 更多