Python LIST函数不返回新列表

时间:2012-04-02 20:20:11

标签: python list

考虑到内置的Python List-methods,我遇到了一个问题。

当我学习Python时,我总是认为Python mutators,就像任何值类mutator应该做的那样,返回它创建的新变量。

举个例子:

a = range(5)
# will give [0, 1, 2, 3, 4]
b = a.remove(1)
# as I learned it, b should now be [0, 2, 3, 4]
# what actually happens:
# a = [0, 2, 3, 4]
# b = None

此列表mutator未返回新列表的主要问题是,您不能随后进行多个突变。 假设我想要一个范围从0到5的列表,没有2和3。 返回新变量的mutators应该能够这样做:

a = range(5).remove(2).remove(3)

这是不可能的,如range(5).remove(2) = None

现在,有没有办法在列表中实际进行多次突变,就像我想在我的例子中做的那样?我认为即使是PHP也允许使用Strings进行这些类型的后续突变。

我也找不到所有内置Python函数的好参考。如果有人能找到所有列表mutator方法的实际定义(带有返回值),请告诉我。我能找到的就是这个页面:http://docs.python.org/tutorial/datastructures.html

5 个答案:

答案 0 :(得分:9)

而不是两个变异和返回对象,Python库选择只使用一种方式来使用mutator的结果。来自import this

  

应该有一个 - 最好只有一个 - 显而易见的方法。

话虽如此,对于你想要做的更常见的Python风格是使用列表推导生成器表达式

[x for x in range(5) if x != 2 and x != 3]

您也可以将这些链接在一起:

>>> [x for x in (x for x in range(5) if x != 2) if x != 3]
[0, 1, 4]

上面的生成器表达式具有额外的优势,即它在 O(n)时间运行,因为Python只迭代range()一次。对于大型生成器表达式,甚至对于无限生成器表达式,这都是有利的。

答案 1 :(得分:4)

list和其他可变类型的许多方法都故意返回None,因此您无需考虑是创建新对象还是改变现有对象。唯一可能发生的事情是变异,因为如果创建了一个新对象,它必须由该方法返回,并且不会返回。

您可能已经注意到,编辑字符串的str方法会返回新字符串,因为字符串是不可变的,并且总是返回一个新字符串。

当然,没有任何东西可以阻止你在list et al,上编写一个具有所需行为的.append()子类,尽管这看起来像是一个沉重的锤子摆动只是为了让你链接方法调用。此外,大多数Python程序员不会期望这种行为,使您的代码不那么清晰。

答案 2 :(得分:4)

在Python中,基本上所有改变对象的方法都会返回None

这样你就不会意外地认为你有一个新的对象。

你提到

  

我认为即使是PHP也允许使用Strings进行这些类型的后续突变。

虽然我不记得PHP,通过字符串操作,你可以链式方法调用,因为字符串是不可变的,所以所有字符串方法返回一个新字符串,因为它们不会(不能)更改您调用它们的字符串。

>>> "a{0}b".format(3).center(5).capitalize().join('ABC').swapcase()
'a A3B b A3B c'

答案 3 :(得分:2)

Python或php都没有内置的“mutators”。你可以简单地写多行,比如

a = list(range(5))
a.remove(2)
a.remove(3)

如果要生成新列表,请事先复制旧列表:

a = list(range(5))
b = a[:]
b.remove(2)

请注意,在大多数情况下,对remove的单一调用表示您应该首先使用set

答案 4 :(得分:-1)

要删除列表中的多个突变,您可以执行以下操作:

a = range(5)
a = [i for j, i in enumerate(a) if j not in [2, 3]]

a将是[0,1,4]