Функция, удаляющая первый экземпляр значения, используя только лямбду, фильтр, отображение и уменьшение - PullRequest
1 голос
/ 01 октября 2019

Я пытаюсь создать функцию, которая будет принимать кортеж и удалять первый экземпляр значения. Например: print(Remove((0, 1, 2, 1, 3), 1)) должен вернуть (0, 2, 1, 3).

Я использую функциональное программирование и не использую предопределенные функции. Мне разрешено использовать только lambda, filter, map и reduce, но больше ничего. Я не могу использовать list.remove или for-loop. Я предполагаю, что функция фильтра будет работать лучше всего для этого. Я выяснил, что следующая функция будет работать для удаления всех экземпляров значения E. Теперь мне нужно знать, как просто удалить первый экземпляр E.

def Remove(T,E):
   return tuple(filter(lambda x: x!=E, T))

Ответы [ 2 ]

0 голосов
/ 01 октября 2019

Это можно сделать с помощью простой рекурсии

  1. Если входной кортеж t пуст, вернуть пустой результат
  2. (индуктивный) В противном случае t равен не пусто - t имеет хотя бы один элемент . Если первый элемент t соответствует удаляемому элементу, x, верните хвост кортежа
  3. (индуктивный). В противном случае t равен , а не пуст и первыйэлемент t не не соответствует элементу для удаления, x. Создайте новый кортеж с первым элементом t и рекурсивным результатом

Нумерованные комментарии ниже соответствуют объяснению выше -

def remove(t, x):
  if not t:       # 1
    return ()
  elif t[0] == x: # 2
    return t[1::]
  else:           # 3
    return (t[0], *remove(t[1::], x))

print(remove((0, 1, 2, 1, 3), 1))
# (0, 2, 1, 3)

Python имеет эксцентричный синтаксис для взаимодействияс элементами коллекций. Определив несколько вспомогательных функций, мы можем установить надежный и последовательный способ написания программ такого типа -

def is_empty(x):
  return not x

def head(x):
  if is_empty(x)
    raise RuntimeError("head called on empty input")
  else:
    return x[0]

def tail(x):
  if is_empty(x)
    raise RuntimeError("tail called on empty input")
  else:
    return x[1::]

def remove(t, x):
  if is_empty(x):
    return ()
  elif head(t) == x:
    return tail(t)
  else:
    return (head(t), *remove(tail(t), x))

print(remove((0, 1, 2, 1, 3), 1))
# (0, 2, 1, 3)
0 голосов
/ 01 октября 2019
numbers = (2, 3, 1, 4, 2, 3, 6)
e = 3  # element to remove
nums_removed = tuple(
    filter(
        lambda x, found=[False, True]: not (not found[0] and x == e and found.reverse() is None),
        numbers
    )
)
print(nums_removed)

Вывод:

(2, 1, 4, 2, 3, 6)

Однако я не могу понять, почему кто-то так сильно хотел бы написать код. Это все равно, что ехать из США в США через Индию.

Смысл в том, чтобы использовать функциональное программирование, когда оно производит более простой и красивый код, и использовать все остальное, что уже доступно, чтобы облегчить жизнь.

Я закончил тем, что написал lambda функцию, которую я сам не совсем понимаю, но она работает. Я продолжал пробовать разные подходы, чтобы увидеть, что работает, потому что мне было скучно. Вы не можете иметь локальные переменные внутри лямбда-функций, поэтому я использовал изменяемый аргумент по умолчанию found для сохранения состояния функции. Я отправил его как ответ, как только он заработал.

Если кто-то хочет добавить объяснение к моему ответу, смело редактируйте его.

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