关于python:在保留原始文件的同时传递列表

Passing a list while retaining the original

所以我在自学python,我对列表有一个问题。我想给我的函数传递一个列表,并在保留原始列表的同时弹出其中的项。如何使python"instance"成为传递的列表,而不是将指针传递给原始列表?

例子:

1
2
3
4
5
6
7
8
9
def burninate(b):
    c = []
    for i in range(3):
        c.append(b.pop())
    return c

a = range(6)
d = burninate(a)
print a, d

输出:[0,1,2][5,4,3]期望输出:[0,1,2,3,4,5][5,4,3]

谢谢!


正如其他答案所建议的,您可以向您的函数提供列表的副本。

作为替代方法,您的函数可以复制参数:

1
2
3
4
5
6
def burninate(b):
    c = []
    b = list(b)
    for i in range(3):
        c.append(b.pop())
    return c

基本上,您需要在头脑中(以及文档中)清楚您的函数是否会更改其参数。在我看来,返回计算值的函数不应更改其参数,而更改其参数的函数不应返回任何内容。示例请参见python的[.sort()、[.extend()、.update()等。显然,有一些异常(如.pop())。

另外,根据您的具体情况,您可以重写函数以避免使用pop()或其他修改参数的函数。例如

1
2
def burninante(b):
    return b[:-4:-1]   # return the last three elements in reverse order


您可以使用如下列表的副本调用burninate()

d = burninate(a[:])

或者,

d = burninate(list(a))

另一种选择是用您的方法复制列表:

1
2
3
4
5
6
7
8
9
10
11
def burninate(b):
    c=[]
    b=b[:]
    for i in range(3):
        c.append(b.pop())
    return c

>>> a = range(6)
>>> b = burninate(a)
>>> print a, b
>>> [0, 1, 2, 3, 4, 5] [5, 4, 3]


一种更易读的方法是:

1
d = burninate(list(a))

这里,list()构造函数基于a创建了一个新的列表。


更通用的解决方案是使用import copy,并在参数上使用copy.copy()


其他版本:

1
2
3
4
5
def burninate(b):
    c = []
    for i in range(1, 4):
        c.append(b[-i])
    return c
1
2
3
4
def burninate(b):
    c = b[-4:-1]
    c.reverse()
    return c

总有一天你会喜欢列表理解:

1
2
def burninate(b):
    return [b[-i] for i in range(1,4)]

您可以使用copy.deepcopy()。


1
burninate = lambda x: x[:-4:-1]