如何通过引用将切片传递给函数

时间:2016-10-02 16:28:00

标签: python python-3.x pass-by-reference slice

如果我有

a = [1, 2, 3]

def foo (arr):
    for i in len (arr): arr [i] += 1

def bar (arr):
    foo (arr[:2])

bar (a)
print (a)

我希望输出为

>>> [2, 3, 3 ]

我该怎么做?

动机:我想要一个优先级队列,我可以冻结最后N个元素,即只将queue[:N]传递给heapq.heappush()。但是,每次我传递一个切片,一个切片或一般的任何函数时,它都会将一个切片副本而不是实际列表发送给该函数,因此我的列表最后会保持不变。

4 个答案:

答案 0 :(得分:1)

使用列表理解并使用[:]的完整切片分配更新初始列表:

def foo(arr):
   arr[:] = [x+1 for x in arr]

试验:

>>> a = [1, 2, 3]
>>> def foo(arr):
...    arr[:] = [x+1 for x in arr]
...
>>> foo(a)
>>> a
[2, 3, 4]

答案 1 :(得分:1)

如果a是numpy数组,这将有效。默认情况下,numpy个切片引用与原始数组相同的内存块。

import numpy as np
a = np.array([1, 2, 3])

def foo(arr):
    for i in range(len(arr)): arr[i] += 1
    # or just arr += 1

def bar(arr):
    foo(arr[:2])

bar(a)
print(a)
# [2, 3, 3 ]

答案 2 :(得分:0)

切片列表会创建一个包含切片内容的新列表,因此arr[:2]会丢失对原始a的引用。

除此之外,按照你所做的那样迭代完全不改变列表,它只是更改item并忽略该值。

如果要更改列表的特定部分,则必须随身携带对原始列表的引用。例如,保留arr,使用enumerate(arr[:2])迭代它的一部分,然后更改arr

a = [1, 2, 3]

def foo(arr):
    for i, item in enumerate(arr[:2]): 
        arr[i] = item + 1

def bar(arr):
    foo(arr)

bar(a)
print(a)

立即打印会产生[2, 3, 3],删除enumerate中的切片会产生[2, 3, 4]。当然,bar这里没有任何意义,您可以放弃它,只需保留foo并立即致电foo(a)

答案 3 :(得分:0)

老实说,不要去切片,我只是传递索引;

a = [1, 2, 3]
def foo(array, start, stop, jmp= 1):
    for idx in range(start, stop + 1, jmp):
        array[idx] += 1

def bar(array):
    foo(array, 1, 2)
bar(a)
print(a)
[1, 3, 4]