2011-11-10 11 views
8

Czy istnieje odpowiednik cons w języku Python? (dowolna wersja powyżej 2,5)LISP przeciw w pytonie

Jeśli tak, to czy jest on wbudowany? A może potrzebuję easy_install dostać moduł?

Odpowiedz

7

W języku Python bardziej typowe jest używanie opartej na tablicach klasy list niż listy połączone w stylu Lisp. Ale nie jest to zbyt trudne do przekonwertowania między nimi:

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

Używanie list i pętli Pythona do emulacji list Lispa wydaje się przesadą. Poza tym, jak zauważył @alberge, ta odpowiedź wykorzystuje listy tablic zamiast list powiązanych. Mam nadzieję, że [ten esej] (http://www.jotflow.com/jot/PythonS-Cons-Car--Cdr/18) daje lepsze rozwiązanie. –

1

Nr cons to szczegół implementacji języków podobnych do Lisp; w Pythonie nie istnieje w sensownym znaczeniu.

+0

, więc nie ma sposobu na "skondensowanie" list takich jak od '[1, 2, [3, 4, 5, [4, 1]]]' do '[1, 2, 3, 4, 5, 4, 1] "? – tekknolagi

+1

Jest, ale 'cons' nie jest to. Zobacz: http://stackoverflow.com/questions/406121/flattening-a-shallow-list-in-python – duskwuff

2

dość trywialnie można zdefiniować klasę, która zachowuje się podobnie jak cons:

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

Jednak będzie to bardzo „wagi ciężkiej” sposób budowania podstawowych struktur danych, które Python nie jest zoptymalizowane pod kątem, tak bym oczekiwać, że wyniki będą znacznie bardziej obciążające procesor/pamięć niż wykonanie czegoś podobnego w Lisp.

3

Należy pamiętać, że listy Pythona są zaimplementowane jako wektory, a nie listy połączone. Możesz wykonać lst.insert(0, val), ale ta operacja to O (n).

Jeśli chcesz strukturę danych, która zachowuje się bardziej jak połączona lista, spróbuj użyć Deque.

5

OSTRZEŻENIE PRZEDŁUŻENIE: Poniższy materiał może nie być praktyczny!

W rzeczywistości, cons nie musi być prymitywny w Lisp, można go zbudować za pomocą λ. Aby uzyskać szczegółowe informacje, patrz Use of lambda for cons/car/cdr definition in SICP. W Pythonie jest przetłumaczony na:

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) 

Teraz car(cons("a", "b")) powinno dać 'a'.

Co to jest? Plan prefiksów :)

Oczywiście można rozpocząć tworzenie listy przy użyciu rekursji cdr. Możesz zdefiniować nil jako pustą parę w Pythonie.

def nil(): return() 

Należy pamiętać, że należy powiązać zmienną za pomocą = w języku Python. Czy mam rację? Ponieważ może mutować zmienną, wolę zdefiniować stałą funkcję.

Oczywiście nie jest to Python, ale Lispy, nie tak praktyczne, ale eleganckie.

Ćwiczenie: Zaimplementuj bibliotekę listy http://srfi.schemers.org/srfi-1/srfi-1.html schematu w języku Python. Po prostu żartuję :)