list [::]和list有什么区别?

时间:2018-09-17 01:40:40

标签: python arrays python-3.x list

这是一个将矩阵顺时针旋转90度的问题,我不明白为什么我不能使用:

matrix = zip(*matrix[::-1])

但是:

class Solution:
    def rotate(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: void Do not return anything, modify matrix in-place instead.
        """
        matrix[::] = zip(*matrix[::-1])

2 个答案:

答案 0 :(得分:3)

方法中的

matrix是对矩阵对象的引用。分配给matrix将更改matrix以引用您新创建的对象,但不会更改原始对象的内容。 matrix[::] =__setitem__所引用的对象上调用matrix,从而相应地更改了对象的内容。

答案 1 :(得分:1)

在Python中,所有分配都将引用绑定到名称。运算符调用现有引用的方法 1 。就您而言,声明

matrix = ...

纯粹是赋值 2 。它计算右侧,并将其绑定到本地函数作用域中的名称matrix。传递时引用的对象matrix均保持不变。

这就是为什么您看不到所做更改的原因。并不是说该功能不能以这种方式工作,而是对旋转后的列表没有任何作用。该函数退出后,数据将被丢弃。

操作

matrix[:] = ...
另一方面,尽管有=符号 3 ,但

并不是语义上的赋值。这是对matrix.__setitem__(...) 4 的调用。与其他任何方法一样,__setitem__方法可以直接在对象上操作,而无需更改其名称绑定。

就索引而言,[:]等同于[::]。它们分别是[0:len(matrix)][0:len(matrix):1]的简写。在这两种情况下,都将使用默认步长。通常,任何包含冒号的索引都将转换为slice对象。缺少的元素设置为None,并替换为此处显示的特定于序列的默认值。


1 某些操作符(例如+=)在调用方法后执行分配。这些称为augmented assignments。但这不是我们现在感兴趣的情况。

2 除了文字assignment statements=)之外,其他一些类型的赋值是def(将功能对象绑定到其名称),{{ 1}}(对类对象的作用相同),class(将模块或模块的元素绑定到名称),将参数传递给函数(将对象绑定到局部参数名称或kwarg)字典键)和import(在每次迭代时将元素从迭代器绑定到循环变量)。

3 从解析器的角度来看,它仍然是assignment,但是对语句的处理完全不同。类似的语句(实际上不是分配)是在实现为描述符的属性(例如for)上使用=运算符。

4 从技术上讲,它更等效于property,但还有一些其他优化。例如,将永远不会搜索type(matrix).__setitem__(matrix, ...)的元类。