Вызов метода метода класса ... n слоев в глубину - PullRequest
0 голосов
/ 28 мая 2020

Я пытаюсь сделать что-то эквивалентное

a=[[[[[1,2,3,4,5]]]]]
res = a.pop().pop().pop()

, которое вернет [[1, 2, 3, 4, 5]], но я хочу иметь возможность выполнять всплывающую последовательность n раз, например, a.pop() for _ in range(n) не будет работать как вызывающий pop () объект a, а не объект a.pop()

Любая подсказка о том, как это можно сделать в python, и если да, то как это будет вызываться для дальнейшего использования? Ближайшее, что я смог найти, - это оператор * для преобразования списка () в отдельные аргументы

Я не хочу делать что-то вроде этого (игнорируя крайние случаи):

tmp=a.pop()
for _ in range(n-1):
    tmp=tmp.pop()

Ответы [ 2 ]

2 голосов
/ 28 мая 2020

Это интересно, но я бы не предлагал вам делать то, что я напишу ниже, потому что это будет нечитабельно.

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

Итак, как я могу выполнять вложенную функцию? В математике это называется композицией функций (например, f(g(h(x)) для функций f(x), g(x), h(x)). Единственное, что я могу придумать достаточно близко к этому в Python, - это reduce. Вы можете сократить список функций до одной «сокращенной» функции. Мое решение таково:

import functools
a=[[[[[1,2,3,4,5]]]]]
five = functools.reduce(
           lambda f,g: lambda x: f(g(x)),
           [lambda x: x.pop() for _ in range(5)],
           lambda x:x
       )(a)

Вы получите five == 5 выше. Что выталкивает последний элемент из самого внутреннего списка.

Позвольте мне немного пояснить вышесказанное:

  • functools.reduce() - это создание функции f(f(f(f(f(a))))), которая определяется f(x) как x.pop(). Он вложен пять раз, поэтому я использую range(5) во втором аргументе functools.reduce()
  • Первый аргумент - выполнить вложенность
  • Третий аргумент - создать функцию, которая возвращает сам. Идея для самого внутреннего f(a), нам нужно express как вложенную функцию. Итак, это f(g(a)), которое g(a)=a и f(a)=a.pop()
  • Все это возвращает вызываемый объект. Поэтому мы вызываем его с аргументом a для его выполнения
  • По сути, это эквивалентно запуску a.pop().pop().pop().pop().pop() с a, доступ к которому осуществляется через лямбда-функцию идентификации lambda x: x

Да, сложно и трудно читать. Но это можно сделать в Python.

0 голосов
/ 28 мая 2020

вы можете использовать рекурсию. эта функция принимает список и количество запросов, которые вы хотите выполнить, и возвращает результат

a = [[[[[1, 2, 3, 4, 5]]]]]

def pop_n(l, n):
    item = l.pop()
    if n < 2:
        return item
    else:
        return pop_n(item, n-1)

res = pop_n(a, 3)
print(res)
# [[1, 2, 3, 4, 5]]
...