Как вы возвращаете измененный ссылочный параметр размера массива Python - PullRequest
0 голосов
/ 23 декабря 2018

Это вопрос передачи параметров функции Python.Я хочу, чтобы функция Python корректировала размер массива, который является одним из справочных параметров функций.

Содержимое переданного массива изменяется внутри и снаружи функции.Каким-то образом обновленный размер / форма объекта массива не экспортируется из функции, хотя я думал, что Python передает параметры по ссылке.Я новичок в программировании на Python и ожидал, что все аспекты объекта будут обновлены по ссылке.Нужно ли явно «экспортировать» изменения?

#!/opt/local/bin/python2.7

# Function Test returning changed array
import numpy

def adjust( a1, a2 ) :
  " Adjust passed arrays (my final function will choose which one to adjust from content) "
  print str(a1.shape) + " At start inside function"
  a1[-1,0] = 99
  a1 = numpy.delete(a1, -1, 0)
  print str(a1.shape) + " After delete inside function"
  return None


d1 = numpy.array( [ [ 1,  2,  3],
                    [11, 12, 13],
                    [21, 22, 23],
                    [31, 32, 33]  ] )
d2 = numpy.array( [ [ 9,  8,  7],
                    [19, 18, 17]  ] )

print str(d1.shape) + " At start"
# Let us delete the last row
d1 = numpy.delete(d1, -1, 0)
print str(d1.shape) + " After delete"
# Worked as expected

# So far so good, now do it by object reference parameters in a function......
adjust( d1, d2 )
print d1
print str(d1.shape) + " After function delete return"
# Reference fails to update object properties

Каким-то образом объект массива, на который ссылаются, не получает обновленных атрибутов размера / формы.В возвращаемом массиве должно быть только 2 строки.

(4, 3) At start
(3, 3) After delete
(3, 3) At start inside function
(2, 3) After delete inside function
[[ 1  2  3]
 [11 12 13]
 [99 22 23]]
(3, 3) After function delete return

Таким образом, основной / глобальный код работает должным образом, функция не может отрегулировать размер, но теперь удаленная строка в конце показывает обновленные данные,Помня о том, что последняя функция выберет один из нескольких параметров для настройки, как мне полностью экспортировать измененную форму / размер параметра из функции?

Ответы [ 2 ]

0 голосов
/ 14 января 2019

Другое решение (менее эффективное, чем простой вызов) .....

Я уверен, что натолкнулся на несколько примеров "удаления на месте" при поиске ответа, не вполне осознавая, что это могло бытьМне нужно было в то время.Хитрость заключается в том, чтобы удостовериться, что локальные имена (формальные параметры) не переназначаются новым ссылкам с помощью «=» в функции, поэтому таким образом все изменения вносятся в те же ссылки (имена), что и переданные аргументы (фактическиепараметров) к функции.

Вызов Python по ссылке, возможно, больше похож на вызов по указателю значения, учитывая то, как имена могут вести себя при присваивании (=).

# Warning Unsafe - array parameter resized in place
# Insure array is not in use on calling
# Requires array to be in C order
def inplace_row_delete( a, r, c=1 ) :
  " Dangerously and inefficiently delete a row in-place on a numpy array (no range checking) "
  # a  reference to the numpy array to have a row deleted from
  #    This routine takes care not to re-assign this in effect "local" name
  #    so as to change the called array in place.
  # r  row to delete in numpy array a
  # c  Nr of rows from r (inclusive) to delete (default 1)

  rows = a.shape[0]
  if (r < 0):
    # support -ve indexing back from end
    r = rows + r
  # Move all the elements after row r, forward one (or c) place(s)
  for index in range(r, rows - c):
    a[index] = a[index + c]

  # Now make the array smaller, disposing of the last (now repeated) element(s)
  # tuples are immutable, but we need to reduce the first element (for the rows in
  # the array) by 1 (c), but keep however many others there are, the same.
  sh    =  list(a.shape)
  sh[0] -= c
  sh    =  tuple(sh)
  # This numpy re-size happens inplace
  # REQUIRES C order
  a.resize(sh, refcheck=False)
  return None
0 голосов
/ 23 декабря 2018

https://docs.scipy.org/doc/numpy-1.15.1/reference/generated/numpy.delete.html

Возвращает : "Копия arr с удаленными элементами, указанными в obj. Обратите внимание, что удаление не происходит на месте. ЕслиОсь None, out - плоский массив. "

Это означает, что delete не изменяет исходный массив - он просто делает копию.Сравните это с присваиванием элемента a1[-1,0] = 99, которое изменяет массив на месте.Я не верю, что numpy допускает изменение размера динамического массива по соображениям производительности.

Что касается вашей путаницы, параметр передается по ссылке (поэтому массив в a1 изначально совпадает с массивом в d1).Однако, присваивание a1 = numpy.delete(a1, -1, 0) является перепривязкой имени a1, без изменения массива, на который оно указывает, поэтому d1 не изменяется.

Если это не имеет смысла, вы должны прочитать больше о том, как переменные работают в Python https://mathieularose.com/python-variables/,, но в основном имена (например, 1026 *, d1) являются словарными ключами, иприсвоение имени изменяет значение, связанное с этим ключом, что не влияет на другие ключи, связанные с этим значением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...