Lisp минусы в python

есть ли эквивалент cons в Python? (любой версии выше 2,5)

Если да, то встроенный? Или мне нужно easy_install получить модуль?

5 ответов


в Python более типично использовать массив на основе list класс, чем связанные списки в стиле 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]

предупреждение вперед: материал ниже не может быть практичным!

на самом деле cons не нужно быть примитивным в Lisp, вы можете построить его с λ. См.использование лямбда для определения минусов / автомобилей / cdr в SICP для сведения. В 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. Я прав? Поскольку он может мутировать переменную, я бы предпочел определить постоянную функцию.

конечно, это не питон, но Лиспи, не так практично, но элегантно.

упражнение: реализация библиотеки списков http://srfi.schemers.org/srfi-1/srfi-1.html схемы в Python. Просто шучу:)


обратите внимание, что списки Python реализованы как векторы, а не как связанные списки. Вы могли бы сделать lst.insert(0, val), но эта операция O (n).

Если вы хотите, чтобы структура данных, которая ведет себя как связанный список, попробуйте использовать очереди.


Вы можете достаточно легко определить класс, который ведет себя как cons:

class Cons(object):
    def __init__(self, car, cdr):
        self.car = car
        self.cdr = cdr

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


нет. cons - это деталь реализации Lisp-подобных языков; она не существует в каком-либо значимом смысле в Python.