调用 class 方法的方法的 ... n 层深

Calling class method's method's ... n layers deep

我正在尝试做等同于

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

这会 return [[1, 2, 3, 4, 5]],但我希望能够执行弹出序列 n 次,所以类似 a.pop() for _ in range(n) 不会工作,因为它在 a 对象上调用 pop() 而不是 a.pop() 对象

关于如何在 python 中完成此操作的任何线索,如果是这样,它将被称为什么以供将来参考?我能找到的最接近的东西是将 list() 转换为单独参数的 * 运算符

我不想做这样的事情(忽略边缘情况):

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

你可以使用递归。这个函数需要一个列表和你想要执行的弹出次数以及returns结果

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

这个很有趣,但我不建议你按照我下面写的去做,因为它会不可读。

首先你不想显式地创建一个函数。你想要一个像表达式这样的列表理解来做到这一点。这是规则。

那么如何实现嵌套函数呢?在数学中,它被称为函数组合(即,f(g(h(x)) 对应函数 f(x)g(x)h(x))。在 Python 中,我能想到的唯一与此足够接近的是 reduce。您可以将函数列表缩减为单个 "reduced" 函数。我的解决方案是:

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()。它嵌套了五次,所以我在 functools.reduce()
  • 的第二个参数中使用 range(5)
  • 第一个参数是嵌套
  • 第三个参数是创建一个returns自身的函数。思路是针对最里面的f(a),我们需要将其表达为嵌套函数。所以它是 f(g(a)) 其中 g(a)=af(a)=a.pop()
  • 这整个东西 returns 是一个可调用对象。所以我们用参数a调用它来执行它
  • 本质上,这等同于 运行 a.pop().pop().pop().pop().pop() a 通过身份 lambda 函数访问 lambda x: x

是的,复杂且难以阅读。但是可以在Python.

中完成