繁体   English   中英

关于在Python函数中就地修改列表的方法

[英]About the way to modify the list in-place in a function in Python

如果我尝试按以下方式就地修改“木板”列表,则它不起作用,似乎它会生成一些新的“木板”,而不是就地修改。

def func(self, board):
    """
    :type board: List[List[str]]
    """
    board = [['A' for j in range(len(board[0]))] for i in range(len(board))]

    return 

我必须做这样的事情才能就地进行修改,这是什么原因? 谢谢。

    for i in range(len(board)):
        for j in range(len(board[0])):
            board[i][j] = 'A'

您似乎了解这两种情况之间的区别,并且想知道为什么Python使您以不同的方式处理它们?

我必须做这样的事情才能就地进行修改,这是什么原因?


创建新副本是有价值的。 因此,使其成为一种表达是有意义的。 实际上,列表推导如果不是表达式,将毫无用处。

就地改变列表是没有价值的。 因此,没有理由使其成为表达式,实际上这样做很奇怪。 当然,您可以提出某种价值(例如,列表被突变)。 但这与Python设计中的其他所有内容都不一致: spam.append(eggs)不返回spam ,它不返回任何内容。 spam = eggs没有价值。 等等。


其次,理解风格很好地融入了可迭代的范式,这是Python的基础。 例如,请注意,只需将[…]更改为(…) ,就可以将列表推导转换为生成器推导(这使您可以对按需计算的值进行延迟的迭代(…) 突变会有什么有用的等效物?

使转换副本更方便也鼓励人们使用非变异样式,这通常可以为许多问题提供更好的答案。 当您想知道如何避免编写三行嵌套语句来对某些全局变量进行突变时,答案是停止对该全局变量进行突变,而是传递一个参数并返回新值。

此外,语法是从Haskell中,在没有突变的复制。


但是,所有那些“经常”和“通常”并不意味着“从不”。 有时(除非您设计的语言没有变异),否则您需要就地执行操作。 这就是为什么我们list.sort以及sorted (并且已经做了很多工作来优化list.sort的地狱;这不仅仅是事后的想法。)

Python不会阻止您这样做。 它只是不弯腰远,使之容易,因为它为复制。

那没有修改它。 列表理解语法[x for y in z]在创建一个新列表。 此语法不会修改原始列表。 使函数内部的名称指向新列表不会更改函数外部名称所指向的列表。

换句话说,当调用函数时,python传递对对象的引用,而不是对名称的引用,因此,没有简单的方法来更改函数外部的变量名所指向的对象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM