В python или coffeescript, почему list.append не возвращает сам список? рекурсия может быть намного проще, если так - PullRequest
3 голосов
/ 14 сентября 2011

рассмотрите следующий код, если insert () возвращает сам список.

def sieve(l):
  if not len(l):
    return []
  return sieve(filter(lambda x: x%l[0] != 0, l)).insert(0, l[0])

На данный момент мы должны полагаться на вспомогательную функцию для возврата списка после вставки.

def cons(a, l):
  l.insert(0, a)
  return l

def sieve(l):
  if not len(l):
    return []
  return cons(l[0], sieve(filter(lambda x:x%l[0] != 0, l)))

Точка изменяемого / неизменяемого объекта полностью действительна.

Однако для списков, которые являются изменяемыми, IMHO, API append () может сделать еще один шаг, чтобы вернуть сам список, а не нет.возвращать что-нибудь.Java StringBuilder является хорошим примером.Я могу рекурсивно выполнить цепочечное добавление на объекте stringbuilder .... Просто хотелось бы, чтобы и здесь это было.

Ответы [ 3 ]

14 голосов
/ 14 сентября 2011

В Python очень важно, чтобы новички узнали, какие объекты являются «неизменяемыми» и не могут быть изменены, а какие «изменяемыми» и могут быть изменены - в последнем случае каждые ссылка на объект видит то же самое изменение.Это действительно, кажется, смущает новичков.«Я невинно назвал эту функцию, которую написал, и внезапно моя копия списка тоже изменилась!»

Так что у Python есть соглашение: неизменяемые объекты, когда вы просите их внести корректировку, возвращает недавно созданный объект, который является ответом - так:

a = 'my string'
b = a.replace('y', 'e')

заставляет b получить совершенно новую строку, в то время как a сохраняет свое первоначальное значение.Очевидно, что такие методы должны возвращать значение, поскольку вы никогда не сможете увидеть это изменение, проверив сам исходный неизменный объект.

Но когда вы просите изменяемый объект изменить себя, он не возвращает себя, потому что не нужно - вы можете увидеть изменение, просто посмотрев на исходный объект снова!Это важный семантический сигнал в Python: если такой метод, как append(), не возвращает новый объект, вы можете увидеть это изменение, просто взглянув на старый объект, и , так же как и все остальные со ссылкой настарый объект.

4 голосов
/ 14 сентября 2011

Поскольку вы спрашивали о CoffeeScript ...

Метод push изменяет массив на месте.Вместо того, чтобы возвращать недавно измененный массив, он возвращает только что добавленное вами значение.Это не интуитивно понятно, но это может быть полезно.Например, вы можете написать что-то вроде

getNewValue -> cache.push fetchValue()

, которое в одну строку извлекает значение, добавляет его к cache и возвращает его из getNewValue.

.Метод concat, с другой стороны, не изменяет исходный массив, а возвращает возвращенную модифицированную копию.Предполагается, что он будет использоваться для объединения двух массивов, но значения, не являющиеся массивами, будут принудительно приведены, поэтому вы можете использовать его как замену push, если хотите:

arr = [1, 2, 3]
arr = arr.concat 4
console.log arr  # [1, 2, 3, 4]

Полная документация по методам массива JavaScriptдоступно по MDN .

0 голосов
/ 14 сентября 2011

Почему бы просто не создать ссылку?Я думаю, что это сделает код более читабельным.

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