cons
在 Python 中是否有等价物?(任何高于 2.5 的版本)
如果是这样,它是内置的吗?还是我需要easy_install
一个模块?
提前警告:以下材料可能不实用!
实际上,cons
在 Lisp 中不需要是原始的,你可以用 λ 来构建它。有关详细信息,请参阅SICP 中使用 lambda 进行 cons/car/cdr 定义。在 Python 中,它被翻译为:
def cons(x, y):
return lambda pair: pair(x, y)
def car(pair):
return pair(lambda p, q: p)
def cdr(pair):
return pair(lambda p, q: q)
现在,car(cons("a", "b"))
应该给你'a'
。
那个怎么样?前缀方案:)
显然,您可以使用cdr
递归开始构建列表。您可以nil
在 Python 中定义为空对。
def nil(): return ()
请注意,您必须=
在 Python 中使用绑定变量。我对吗?由于它可能会改变变量,我宁愿定义常量函数。
当然,这不是 Pythonic 而是 Lispy,既不实用又优雅。
练习:用Python实现Scheme的List Library http://srfi.schemers.org/srfi-1/srfi-1.html。只是在开玩笑 :)
list
在 Python 中,使用基于数组的类比使用Lisp 样式的链表更典型。但是在它们之间转换并不难:
def cons(seq):
result = None
for item in reversed(seq):
result = (item, result)
return result
def iter_cons(seq):
while seq is not None:
car, cdr = seq
yield car
seq = cdr
>>> cons([1, 2, 3, 4, 5, 6])
(1, (2, (3, (4, (5, (6, None))))))
>>> iter_cons(_)
<generator object uncons at 0x00000000024D7090>
>>> list(_)
[1, 2, 3, 4, 5, 6]
请注意,Python 的列表是作为向量实现的,而不是作为链表。您可以这样做lst.insert(0, val)
,但该操作是 O(n)。
如果您想要一个行为更像链表的数据结构,请尝试使用Deque。
您可以非常简单地定义一个行为类似于cons
:
class Cons(object):
def __init__(self, car, cdr):
self.car = car
self.cdr = cdr
然而,这将是构建基本数据结构的一种非常“重量级”的方法,Python 并未针对该数据结构进行优化,因此我希望结果比在 Lisp 中执行类似操作更占用 CPU/内存。
在 Python 3 中,您可以使用 splat 运算符*
通过编写[x, *xs]
. 例如:
>>> x = 1
>>> xs = [1, 2, 3]
>>> [x, *xs]
[1, 1, 2, 3]
如果您更喜欢将其定义为函数,那也很容易:
def cons(x, xs):
return [x, *xs]
No.cons
是类 Lisp 语言的实现细节;它在 Python 中不存在任何有意义的意义。