传值列表功能(Pass list to function by value)

2019-07-21 11:20发布

我想按值传递一个列表到函数。 默认情况下,列表和其他复杂的对象通过参考作用。 下面是一些desision:

def add_at_rank(ad, rank):
    result_ = copy.copy(ad)
    .. do something with result_
    return result_

可以这样写短? 换句话说,我想不会改变广告

Answer 1:

您可以使用[:] ,但是对于包含列表清单(或其他可变对象),你应该去copy.deepcopy()

lis[:]等效于list(lis)copy.copy(lis)并返回列表的浅表副本。

In [33]: def func(lis):
    print id(lis)
   ....:     

In [34]: lis = [1,2,3]

In [35]: id(lis)
Out[35]: 158354604

In [36]: func(lis[:])
158065836

当使用deepcopy()

In [41]: lis = [range(3), list('abc')]

In [42]: id(lis)
Out[42]: 158066124

In [44]: lis1=lis[:]

In [45]: id(lis1)
Out[45]: 158499244  # different than lis, but the inner lists are still same

In [46]: [id(x) for x in lis1] = =[id(y) for y in lis]
Out[46]: True

In [47]: lis2 = copy.deepcopy(lis)  

In [48]: [id(x) for x in lis2] == [id(y) for y in lis]  
Out[48]: False


Answer 2:

这可能是一个有趣的用例的装饰功能。 事情是这样的:

def pass_by_value(f):
    def _f(*args, **kwargs):
        args_copied = copy.deepcopy(args)
        kwargs_copied = copy.deepcopy(kwargs)
        return f(*args_copied, **kwargs_copied)
    return _f

pass_by_value需要一个功能f作为输入,并创建一个新的功能_f深-复制它的所有参数,然后将它们传递给原有的功能f

用法:

@pass_by_value
def add_at_rank(ad, rank):
    ad.append(4)
    rank[3] = "bar"
    print "inside function", ad, rank

a, r = [1,2,3], {1: "foo"}
add_at_rank(a, r)
print "outside function", a, r

输出:

"inside function [1, 2, 3, 4] {1: 'foo', 3: 'bar'}"
"outside function [1, 2, 3] {1: 'foo'}"


Answer 3:

浅表副本通常是不够好,并有可能比玉米粥深拷贝更快。

你可以利用这一点,如果你正在为修改result_没有变异的项目/属性,它包含

举个简单的例子,如果你有一个棋盘

board = [[' ']*8 for x in range(8)]

你可以做一个浅拷贝

board2 = copy.copy(board)

它是安全的追加/插入/流行/删除/替换从项目board2 ,但没有列出它包含的内容。 如果你想修改contianed列表中的一个,你必须创建一个新的列表,并replace现有的一个

row = list(board2[2])
row[3] = 'K'
board2[2] = row

这是一个多一点的工作,但很多时间和存储更高效



Answer 4:

广告的情况下是列表 ,你可以简单的调用函数为add_at_rank(ad + [], rank)

这将创建一个列表的新实例每次调用函数时,equivalented 广告的该值。

>>>ad == ad + []
True

>>>ad is ad +[]
False

纯Python的:)



文章来源: Pass list to function by value