Ist es richtig, die Graviszeichen / Komma Idiom in einer verwenden (Schleife ...)?

StackOverflow https://stackoverflow.com/questions/101487

  •  01-07-2019
  •  | 
  •  

Frage

Ich habe einige Codes, die Punkte (Consed ganze Zahlen) von einer Schleife sammelt, die etwa wie folgt aussieht:

(loop
    for x from 1   to     100
    for y from 100 downto 1
        collect `(,x . ,y))

Meine Frage ist, ist es richtig, `(,x . ,y) in dieser Situation zu benutzen?

Edit: Diese Probe ist nicht über eine Tabelle von 100x100 Elementen zu erzeugen, hier der Code illustriert nur die Verwendung von zwei Schleifenvariablen und die consing ihrer Werte. Ich habe die Schleife bearbeitet, um dies deutlich zu machen. Die eigentliche Schleife I hängt Verwendung von mehreren anderen Funktionen (und ist ein Teil von einer selbst), so dass es sinnvoller, die Anrufe mit wörtlichen ganzen Zahlen zu ersetzen und die Schleife aus der Funktion zu ziehen.

War es hilfreich?

Lösung

Es wäre viel 'besser' sein zu tun (cons x y).

Aber die Frage beantworten, , es ist nichts falsch mit, dass :) tun (außer es macht ein bisschen langsamer).

Andere Tipps

Ich denke, die Antwort hier Ressourcennutzung ist (nach von Dieser Beitrag )

zum Beispiel in clisp:

[1]> (time
         (progn
             (loop
                 for x from 1 to 100000
                 for y from 1 to 100000 do
                     collect (cons x y))
         ()))
WARNING: LOOP: missing forms after DO: permitted by CLtL2, forbidden by ANSI
         CL.
Real time: 0.469 sec.
Run time: 0.468 sec.
Space: 1609084 Bytes
GC: 1, GC time: 0.015 sec.
NIL
[2]> (time
         (progn
             (loop
                 for x from 1 to 100000
                 for y from 1 to 100000 do
                     collect `(,x . ,y)) ;`
         ()))
WARNING: LOOP: missing forms after DO: permitted by CLtL2, forbidden by ANSI
         CL.
Real time: 0.969 sec.
Run time: 0.969 sec.
Space: 10409084 Bytes
GC: 15, GC time: 0.172 sec.
NIL
[3]>

dsm: Es gibt ein paar seltsame Dinge über Ihren Code hier . Beachten Sie, dass

(loop for x from 1 to 100000
  for y from 1 to 100000 do
  collect `(,x . ,y))

entspricht:

(loop for x from 1 to 100
   collecting (cons x x))

das ist wahrscheinlich auch nicht ganz das, was Sie bestimmt. Beachten Sie drei Dinge: Erstens, wie Sie es geschrieben haben, x und y die gleiche Rolle haben. Sie haben wahrscheinlich zu nisten Schleifen gemeint. Zweitens Ihre do nach dem y ist falsch, da es nicht lispeln Form es finden. Drittens sind Sie richtig, dass Sie hier den Graviszeichen Ansatz verwenden könnten, aber es macht den Code schwerer zu lesen und nicht idiomatische für keinen Gewinn, so am besten vermieden werden.

Erraten, was Sie eigentlich gedacht, man könnte so etwas wie diese (mit Schleife) tun:

(loop for x from 1 to 100 appending 
  (loop for y from 1 to 100 collecting (cons x y)))

Wenn Sie nicht über die Schleife Makro mögen (wie Kyle), können Sie eine weitere Iteration konstruieren wie

verwenden
(let ((list nil)) 
   (dotimes (n 100) ;; 0 based count, you will have to add 1 to get 1 .. 100
     (dotimes (m 100) 
       (push (cons n m) list)))
   (nreverse list))

Wenn Sie sich selbst tun, diese Art der Sache viel zu finden, sollten Sie vielleicht eine allgemeinere Funktion für die Überquerung Listen schreiben, dann geben sie diese Listen von ganzen Zahlen

Wenn Sie wirklich ein Problem mit Iteration haben, nicht nur Schleife, können Sie diese Art der Sache tun rekursiv (aber beachten Sie, dass dies nicht Schema, Ihre Implementierung kann TCO nicht garantiert). Die Funktion "genint" gezeigt von Kyle

Warum nicht einfach

(cons x y)

By the way, habe ich versucht, den Code in CLISP zu laufen und es nicht wie erwartet. Da ich hier kein großer Fan der Schleife Makro bin, wie Sie das Gleiche erreichen könnte rekursiv:

(defun genint (stop)
  (if (= stop 1) '(1)
      (append (genint (- stop 1)) (list stop))))

(defun genpairs (x y)
  (let ((row (mapcar #'(lambda (y)
                        (cons x y))
                        (genint y))))
    (if (= x 0) row
        (append (genpairs (- x 1) y)
                row))))

(genpairs 100 100)
scroll top