在各种Lisps a 适当的清单 是要么 nil (空值)或 缺点 单元格,其中第一个(head,first,car)值指向一个值,第二个(tail,rest,cdr)指向另一个正确的列表。各种其他函数式编程语言实现了这种头和尾功能,包括Erlang和Scala。在Common Lisp和Emacs Lisp中,您可以无限递归地找到列表的尾部:

(rest (rest (rest (rest (rest (rest ()))))))

它会屈服的 nil.我想在Python中模拟这种行为。当然,为了性能,我最好坚持使用本机数据类型,这些数据类型经过了大量优化,所以这只是为了锻炼。我的代码是:

class MyList:
    def __init__(self, *xs):
        self._x = []
        self._x.extend(xs)
        self.is_empty = not xs
        self.head = xs[0] if xs else None
        self.tail = MyList(*xs[1:]) if xs[1:] else MyList([])

然而调用 tail 现在输入递归并导致最大递归深度错误。我怎样才能使下面这样的表达成为可能?换句话说,如何在Python中创建适当列表的功能?

a = MyList(1,2)
my_list.tail.tail.tail.tail.tail.tail

相关的问题,但没有回答我的问题: Python中的LISP缺点

有帮助吗?

解决方案

我已经尝试重写你的例子了一下-这似乎对我有用,而不会吹堆栈。

class MyList(object):
    def __init__(self, *xs):
        self._x = xs if all(xs) else tuple()
        self.head = xs[0] if xs else None

    @property
    def is_empty(self):
        return not self._x

    @property
    def tail(self):
        return MyList(self._x[1:]) if self._x[1:] else MyList([])

s = MyList(1, 2)
print s.tail.tail.tail.tail.tail.tail

其他提示

而不是试图创建你的类并将其绑定到一个列表,也许你应该编写你自己的链表(这基本上是lisps的工作原理,包含一个元素的节点链和下一个节点(代表列表的其余部分)。

我的蟒蛇有点生锈了,但我要刺一下.考虑这个伪代码:

class WugList:
    def __init__(self, *xs):
        self.head = xs[0] if (len(xs) > 0) else None
        self.tail = WugList(xs[1:]) if (len(xs) > 0) else self
        self.is_empty = (len(xs) > 0)

    def car(self):
        return self.head

    def cdr(self):
        return self.tail

然后,您应该能够使用以下内容:

derp = WugList([1,2,3,42,69,9001])
a = derp.car()                   # 1
b = derp.cdr().car()             # 2
c = derp.cdr().cdr().cdr().car() # 42

# chaining cdr infinitely is possible because the last node's head is None
# and its tail is itself
d = derp.cdr().cdr().cdr().cdr().cdr().cdr().cdr().cdr().cdr().cdr()
              .cdr().cdr().cdr().cdr().cdr().cdr().cdr().cdr().cdr()
              .cdr().cdr().cdr().cdr().cdr().cdr().cdr().cdr().car() # None

如果你想无限地得到 tail 列表的属性,你需要使用 property.这样,直到你要求它,这就防止了无限递归尾不进行评估。

class MyList:
    def __init__(self, *xs):
        self._x = []
        self._x.extend(xs)
        self.is_empty = not xs
        self.head = xs[0] if xs else None

    @property
    def tail(self):
        return MyList(*self._x[1:])

a = MyList(1,2)
print a._x
# [1, 2]
print a.tail._x
# [2]
print a.tail.tail._x
# []
print a.tail.tail.tail._x
# []
print a.tail.tail.tail.tail._x
# []
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top