2016-10-02 4 views
0

Если у меня естьКак передать кусок в функцию по ссылке

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(). Но каждый раз, когда я передаю фрагмент, к нему или к какой-либо функции вообще, он отправляет копию фрагмента, а не фактический список функции, и поэтому мой список остается неизменным в конце.

+0

У вас есть еще одна проблема: 'для элемента в arr: item + = 1' также не изменит список. –

+0

Создание среза массива делает другой объект. –

+0

и что такое 'arr [: 2])' когда вывод '[2, 3, 4]' (добавляет 1 ко всем элементам) –

ответ

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] 
+0

Спасибо. Это решает мою проблему. –

1

Используйте список понимание и обновить первоначальный список, используя полный назначение ломтика с [:]:

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

Trial:

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

приятно, но я думаю, что это не проблема «среза». Я допускаю: вопрос OP непонятен, но посмотрите на 'def bar (arr): foo (arr [: 2])'. Я думаю, что это невозможно. –

+0

Я думаю, что другая функция не отражает цель ОП. Я вижу, что их желаемый результат был четко обозначен –

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]. Конечно, здесь нецелесообразно, вы можете сбросить его и просто оставить foo и сразу позвонить по телефону foo(a).

+0

@ Jean-FrançoisFabre Если вторая проблема заключается в том, как передать срез и сохранить исходную ссылку, тогда это невозможно по тому, как он хотел. Вы можете срезать во время итерации, чтобы достичь аналогичного результата (если это то, что ему нужно). –

+0

да, невозможно так же. –

0

Это будет работать, если 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 ] 
Смежные вопросы