2016-07-11 10 views
-3

Ich kann nicht herausfinden, warum folgende Funktion nicht funktioniert. Ich versuche, eine Liste von Listen zu machen zurückgeben alle Kombinationen zeigt: ((1 5) (1 6) (1 7) (2 5) (2 6) (2 7) (3 5) (3 6) (3 7))Warum sammeln Funktion funktioniert nicht in diesem Lisp-Code

(defun combo3 (list1 list2) 
    (dolist (e1 list1) 
     (dolist (e2 list2) 
      collect '(e1 e2)))) 


> (combo3 '(1 2 3) '(5 6 7)) 
NIL 

Edit: Als Reaktion auf die Antwort, habe ich versucht Schleife Makro mit collect zu verwenden. Sammeln funktioniert nicht in der folgenden Schleife:

(defun combo4 (list1 list2) 
    (loop for element1 in list1 do 
     (loop for element2 in list2 do 
       collect (list element1 element2)))) 

> (combo4 '(1 2 3) '(5 6 7)) 
NIL 

Ich habe versucht, es ohne nconc arbeiten zu lassen. Muss sammeln immer nconc?

+0

'COLLECT' keine Funktion ist. Es ist Teil des 'LOOP'-Makros und kann daher nur innerhalb einer' LOOP' verwendet werden. – jkiiski

+0

Re edit: Das 'COLLECT' in der inneren Schleife erzeugt die Unterlisten, also muss die äußere Schleife eine Klausel haben, um diese zu einer einzigen Liste zusammenzufügen. Außerdem sollten Sie diese 'DO's nicht haben. 'DO' ist nicht Teil des' FOR ... IN ...' Konstrukts, sondern eine separate Anweisung, die zum Ausführen von Formularen verwendet wird (wie 'COLLECT' und' NCONC', außer dass 'DO' das Ergebnis verwirft). – jkiiski

+0

Mögliches Duplikat von [Lisp: Wie erhält man alle möglichen Kombinationen der Elemente aus Listen, die in einer Liste enthalten sind?] (Http://stackoverflow.com/questions/18675913/lisp-how-to-get-all-possible-combinations -of-the-elements-from-lists-contained) – anquegi

Antwort

3

Paar Probleme ...

Erstens ist collect Teil des loop Makro (oder Anlage, wenn Sie bevorzugen), so wird Probleme verursachen, wenn sie innerhalb dolist verwendet.

Zweitens: Selbst wenn collect '(e1 e2)tat etwas sammeln, es (wahrscheinlich) nicht sein, was Sie wollen, da es mit einer Liste wie ((e1 e2) (e1 e2) (e1 e2) (e1 e2) (e1 e2) (e1 e2)) enden würde.

Was Sie (wahrscheinlich) wollen, ist so etwas wie:

(defun cross-product (list1 list2) 
    (loop for element1 in list1 
     nconc (loop for element2 in list2 
       collect (list element1 element2)))) 
+0

Es funktioniert nicht ohne nconc. Bitte beachte die Bearbeitung in meiner Frage. – rnso

+0

@rnso Die innere Schleife verwendet 'collect', um drei Listen zu erstellen,' ((1 4) (1 5) (1 6)) 'und ähnlich für 2 und 3. Diese werden an die äußere Schleife zurückgegeben, wo wir wollen Kombiniere sie. Dies kann entweder mit "nconc" oder "append" geschehen, aber in diesem Fall wissen wir, dass wir neue Listen haben, also können wir auch 'nconc' verwenden, um sie destruktiv zu verketten. Du brauchst eine Art Akkumulation in der äußeren Schleife, sonst gibt es nur 'nil' zurück. In der Regel sollten Sie Ihre Frage nicht bearbeiten, um eine neue Frage zu stellen, sondern einfach eine neue Frage stellen. – Vatine

Verwandte Themen