2011-11-10 13 views
8

Esiste un equivalente di cons in Python? (qualsiasi versione sopra 2.5)LISP cons in python

Se è così, è integrato? O ho bisogno di easy_install ottenere un modulo?

risposta

7

In Python, è più comune utilizzare la classe list basata su array rispetto agli elenchi collegati in stile Lisp. Ma non è troppo difficile da convertire tra di loro:

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

L'uso delle liste e dei loop di Python per emulare gli elenchi di Lisp sembra eccessivo. Inoltre, come ha sottolineato @alberge, questa risposta utilizza liste di array invece di elenchi concatenati. Spero che [questo saggio] (http://www.jotflow.com/jot/PythonS-Cons-Car--Cdr/18) dia una soluzione migliore. –

1

No. cons è un dettaglio di implementazione di lingue simili a Lisp; non esiste in alcun senso significativo in Python.

+0

quindi non c'è modo di "condensare" liste come da '[1, 2, [3, 4, 5, [4, 1]]] a' [1, 2, 3, 4, 5, 4, 1] '? – tekknolagi

+1

C'è, ma 'cons' non è vero? Vedi: http://stackoverflow.com/questions/406121/flattening-a-shallow-list-in-python – duskwuff

2

È possibile piuttosto banalmente definire una classe che si comporta molto simile cons:

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

Tuttavia, questo sarà un modo molto 'pesante' per costruire strutture di dati di base, che Python non è ottimizzato per, quindi vorrei aspettarsi che i risultati siano molto più intensi in termini di CPU/memoria rispetto a qualcosa di simile in Lisp.

3

Si noti che gli elenchi di Python sono implementati come vettori, non come elenchi collegati. Potresti fare lst.insert(0, val), ma quell'operazione è O (n).

Se si desidera una struttura dati che si comporta più come un elenco collegato, provare a utilizzare Deque.

5

AVVISO AVANTI: Il materiale sottostante potrebbe non essere pratico!

In realtà, cons non deve essere primitivo in Lisp, è possibile costruirlo con λ. Vedere Use of lambda for cons/car/cdr definition in SICP per dettagli. In Python, si è tradotto in:

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) 

Ora, car(cons("a", "b")) dovrebbe darvi 'a'.

Come è? Schema prefisso :)

Ovviamente, è possibile iniziare la costruzione della lista utilizzando la ricorsione cdr. È possibile definire nil come coppia vuota in Python.

def nil(): return() 

Si noti che è necessario associare variabile utilizzando = in Python. Ho ragione? Dal momento che potrebbe mutare la variabile, preferirei definire la funzione costante.

Naturalmente, questo non è Pythonic ma Lispy, non è così pratico ma elegante.

Esercizio: implementare la libreria di elenchi http://srfi.schemers.org/srfi-1/srfi-1.html di Scheme in Python. Sto scherzando :)