Распаковка кортежей похожа на Python, но в Common Lisp - PullRequest
12 голосов
/ 16 мая 2011

Есть ли способ присвоить значения списка списку символов в Common Lisp, аналогично тому, как вы можете присваивать значения кортежа переменным в Python?

x, y, z = (1, 2, 3)

Что-то вроде

(setq '(n p) '(1 2))

Где n и p теперь равны 1 и 2 соответственно. Выше было просто, как я думал об этом в моей голове, но это не работает. Я пытался использовать apply следующим образом:

(apply setq '('(n p) '(1 2)))

Я новичок в Лиспе, поэтому, если это что-то явно очевидное, постарайтесь не быть слишком резким и, пожалуйста, направьте меня в правильном направлении! Спасибо.

PS: я видел пост об этом в Scheme и похожий пост о расширении кортежей в Common Lisp, но они не очень помогли ответить на мой вопрос 1), потому что я не использую Scheme, и 2 ) потому что ответом с самым высоким рейтингом было просто слово apply.

Ответы [ 3 ]

12 голосов
/ 16 мая 2011

Используйте DESTRUCTURING-BIND , что может сделать намного больше, чем распаковка кортежей.Как присвоение по ключевым словам, необязательные параметры и т. Д. Действительно, все, что вы можете сделать со списком параметров функции.

Но если у вас нет списка, который нужно деструктурировать, и вы хотите установить кучу переменныходновременно используйте PSETF :

(psetf n 1
       p 2)

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

# Python
n, p = p, n
x, y, z = z, x, y
;; Lisp
(psetf n p
       p n)
(psetf x z
       y x
       z y)

На самом деле, вы, вероятно, можете обойтись без обыденного LET.

Кроме того, не беспокойтесь о SETQ.Используйте SETF / PSETF, потому что они лучше, и, кроме того, единственный способ выполнить определенные типы назначений.

9 голосов
/ 16 мая 2011

Похоже, destruuring-bind (это далеко внизу) может делать то, что вы хотите.

Также описание HyperSpec , но я думаю, что другая ссылка демонстрирует это лучше.

(destructuring-bind (x y z) (list 1 2 3) (+ x y z))
6 голосов
/ 16 мая 2011

Для случая, когда у вас есть список и вы хотите присвоить его значения нескольким переменным, DESTRUCTURING-BIND - это то, что нужно.

Тем не менее, для pythonic «вернуть список или кортеж, используйте список или кортеж переменных для присваивания» case, (вероятно) будет проще использовать несколько возвращаемых значений и MULTIPLE-VALUE-BIND.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...