Python:为什么内联分配列表值会返回“无”元素列表?

时间:2017-07-14 00:04:02

标签: python list

我还是Python新手,我一直在制作一个小功能,可以反转列表列表,包括原始列表和里面的列表。这是我的代码:

def deep_reverse(L):
    L.reverse()
    L = [i.reverse() for i in L]

现在这段代码完美无缺,但如果我做了一些小改动并重新排列这样的行:

def deep_reverse(L):
    L = [i.reverse() for i in L]
    L.reverse()
突然它停止工作了!它只反转内部列表而不是原始列表。将一些调试print()语句放入其中,我可以看到第一个代码在第一行之后反转原始列表并打印出来,但是第二个代码实际上在反转列表后打印了一个包含'None'作为元素的列表。任何人都可以解释为什么这种行为和两个代码之间有什么区别?

2 个答案:

答案 0 :(得分:1)

reverse()函数就地反转列表并返回None,这解释了奇怪的行为。正确的实施方式是:

def deep_reverse(L):
  ans = [i[::-1] for i in L]
  ans.reverse()
  return ans

此外,将参数重新分配和/或改变为函数是一个坏主意,它可能会导致意外结果。有时标准库中的函数会出于效率原因(例如sort()reverse())来执行此操作,这没关系 - 但它可能导致混淆,就像您刚刚遇到的那样。除非绝对必要,否则您的代码不必以这种方式编写。

答案 1 :(得分:1)

您的第一个deep_reverse函数已重新分配L,但它不是全局参数,并且不会在您的函数中返回。因此这个变量就丢失了。但是,你正在改变列表,因此修改仍然是它仍然有效的原因!您的原始功能等同于以下内容(请注意,没有最终分配):

def deep_reverse(L):
    L.reverse()
    [i.reverse() for i in L]

这可能应该使用for循环编写:

def deep_reverse_2(L):
    L.reverse()
    for i in L:
        i.reverse()

L = [[1, 2, 3], [2, 3, 4]]
deep_reverse_2(L)
>>> L
[[4, 3, 2], [3, 2, 1]]

第二个函数不起作用,因为你在函数内部重新分配L(它现在是函数的本地函数,而不是传递给函数的L变量)。如果您使用id进行检查,它们将具有不同的内存位置。如果没有返回任何内容,则会丢失这个新的L列表,以及对其进行的修改。