2012-04-02 113 views
4

我在考虑内置Python List方法时遇到问题。Python LIST函数不返回新列表

当我学习Python时,我一直认为Python的mutators,因为任何值类的mutators都应该做的,返回它创建的新变量。

拿这个例子:

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 

的主要问题与此列表突变没有返回一个新的列表,就是你不能将多个突变之后。 说,我想从0到5的名单,而2和3 存取器返回新的变量应该是能够做到这一点是这样的:

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

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

现在,有没有一种方法可以在列表中实际做多个突变,就像我想在我的例子中做的那样?我认为即使PHP允许这些类型的字符串随后的突变。

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

+1

首先,你要查找的文档http://docs.python.org/library/stdtypes.html#mutable-sequence-types – 2012-04-02 20:23:16

+0

“当我了解到的Python,我一直以为Python的改变者,就像任何值类的mutators应该做的一样,返回它创建的新变量。“ - 你在哪里学习?事实上,在Python中拥有可变状态的对象是非常常见的,而列表就是其中之一。 (字符串不是) – millimoose 2012-04-02 20:39:18

回答

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

嗯,我想在使用列表来排除它时可以很方便地执行如下操作:'[x for x在范围内(5)如果不是在(2,3)中的x)'' – 2012-04-02 23:13:40

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

+2

只有在Python 3中才需要调用'list'。 – agf 2012-04-02 20:25:10

+0

'set'与'list'有什么不同? – 2012-04-03 08:40:41

+0

@stevenroose如果你想通过它的值去除一个特定的元素,那么set将具有O(log n)或者那个操作的O(1)性能。通常,列表的性能将在O(n)左右。 – phihag 2012-04-03 09:18:37

4

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

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

有当然什么都没有耽误你写一个list子类,具有所期望的行为.append()等,虽然这似乎是相当重锤仅仅摆动,让您链方法调用。此外,大多数Python程序员不会期望这种行为,使您的代码不太清晰。

-1

要删除列表上的多个突变,只要你想在你的例子做,你可以这样做:

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

一会[0,1,4]

+1

一个注释:'list.remove(x)'方法删除值为“x”的项目,而不是您的脚本执行的索引“x”处的项目。对于执行相同操作的'range()'列表,它可能不会做正确的事情;} – 2012-04-03 08:42:58

4

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

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

你提到

我想即使PHP允许这些类型的字符串随后的突变。

虽然我不记得PHP,用字符串操作,你可以方法调用,因为字符串是不可变,所以所有的字符串方法返回一个新的字符串,因为它们不(不能)改变你打电话给他们的人。

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