AutoLISPを使い始めたけれど、「リストの扱いがよくわからない…」と感じていませんか?そんな方にぜひ知ってほしいのが、リストの基本を支える関数「car」と「cdr」です。
私はAutoLISPを独学し、業務の自動化・効率化に役立つプログラムを5年以上作成しています。数行で書けるような簡単なプログラムから、1000行以上の少し複雑なプログラムまで様々なツールを作成してきました。
そもそもAutoLISPってなに?という方はこちらの記事をご覧ください。
>>AutoCADユーザー必見!【AutoLISPを覚えるべきメリット5選】デメリットも解説
一見むずかしそうに見えますが、ポイントを押さえればとてもシンプル。当記事ではcarとcdrとは何か、どうやって使うのかをやさしく解説します。
リスト操作のコツをつかめば、AutoLISPでの作業がぐっとスムーズになります。AutoLISPで業務を効率化したい方はぜひ最後までお読みください。
あなたに代わってAutoLISPプログラムを作成します
AutoLISPで作業を自動化したいけど、プログラミングに詳しくないのでツールが作れずにお悩みの方へ。5年以上のAutoLISP経験を活かしてAutoCADを自動化するツールを作成します。既にお持ちのAutoLISPプログラム修正も対応可能です。
AutoCADの面倒くさい作業から解放されたい方は、下記リンク先の「ココナラ」からお気軽にご相談ください。
>>AutoCADが楽になるプログラムを作成します|ココナラ
最短2日で納品します
リストはcarとcdrで成り立つ!AutoLISPのリスト構造を解説

AutoLISPのリストは「先頭の要素」と「残りの要素」の2つに分かれており、「先頭の要素」を「car」、「残りの要素」を「cdr」と呼びます。この”2つのパーツ”の繰り返しがリスト構造の基本です。
リストは単に複数の値を並べただけのデータではありません。「car部」と「cdr部」の2つの要素をペアにした形(ドット対)で構成されています。
ドット対とは、ドット(.)で区切られた2つの値をペアにして保持する構造のこと。このペアが連続してつながることで、複数の要素を持つリスト全体が形成されます。
ちなみにリストとドット対を作成するAutoLISP関数について知りたい方は、こちらの記事をご覧ください。
>>【初心者必読】リストを作成するAutoLISP関数3選|使用例も解説

ドット対はコンスセルとも呼ばれます。
たとえば、(1 2 3)というリストの場合、リスト全体のcar部は1で、cdr部は(2 3) のリストです。
- car部 → 1
- cdr部 → (2 3)
さらに、cdr部である(2 3)に対しても同じように分解を行うと、car部は2、cdr部は(3)となります。
- car部 → 2
- cdr部 → (3)

(3)は要素が1つだけのリストです。
そして、(3)を分解するとcar部は3、cdr部はnilになっています。最後のcdr部は中身が空なので、リストではなくnilとなる点に注意してください。
- car部 → 3
- cdr部 → nil
上記のリスト構造をドット対で表現すると次のようになります。
(1 . (2 . (3 . nil)))
リストの中身を「先頭」と「残り」に分けると、AutoLISPのリスト構造が見えてきます。考え方を覚えるとリストの操作がずっとわかりやすくなるので、ぜひ頭の片隅に置いてみてください。
リストの要素を自在に取り出すAutoLISP関数2選

今回ご紹介するAutoLISP関数は以下の2つです。
- car
- cdr
名前のとおり、前述したcar部とcdr部を取り出すことができます。どちらもリストの要素を取り出す基本的な関数なので、しっかりマスターしましょう。

順番に解説していきます。
car 先頭の要素を取り出す

carはリストの先頭要素である、car部を取り出すAutoLISP関数です。carには次のような特徴があります。
- リスト(ドット対)の最初の要素を返す
- 空のリスト(nil)を与えた場合はnilを返す
- リスト(ドット対)以外ではエラーになる
carは引数として与えられたリスト(ドット対)の先頭要素を返します。たとえば、次のように使用してください。
(car (list A B C)) ; → A
上記の場合、返り値はAです。carは常に、先頭の1つだけを返す特徴があります。リストの2番目以降が必要な場合は、後述するcdrやcadrなどと組み合わせて使ってください。
また、carに空のリスト(nil)を与えたときの返り値はnilです。以下のようなプログラムでもcarはエラーにはなりません。
(car nil) ; → nil
ちなみに、AutoLISPではnilがリストの終端を表す特別な値として扱われています。carはリストの終端(nil)をそのまま返す仕様のため、nilを含んだ条件分岐や再帰処理に活かせます。
AutoLISPの条件分岐についてもっと知りたい方はこちらの記事をご覧ください。
>>【初心者向け】処理を自由に切り替えよう!条件分岐のAutoLISP関数2選
carはリスト(ドット対)を前提とした関数なので、引数がリストでないとエラーになります。数値や文字列に対して使うとエラーになるので注意してください。
(car 123) ; → エラー
(car "abc") ; → エラー

listp関数などでデータの型をしっかり確認しておくと、エラーの予防につながります。
car自体はシンプルな関数ですが、リストのしくみを理解するうえでとても大切な役割を持っています。最初はむずかしく感じるかもしれませんが、少しずつ触れて理解を深めていきましょう。
cdr リストの先頭要素以外を取り出す

cdrはリストの先頭要素以外である、cdr部を取り出すAutoLISP関数です。cdrの特徴は以下のとおり。
- リスト(ドット対)の先頭要素を除いた「残り」を返す
- 空のリスト(nil)を与えた場合はnilを返す
- リスト(ドット対)以外ではエラーになる
cdrは引数としてリスト(ドット対)を与えると、先頭要素を取り除いた「残り」を返します。たとえば、次のように使用します。
(cdr (list A B C)) ; → (B C)
上記のときに返されるのは(B C)です。carが「先頭の要素」を返すのに対し、cdrはその後ろに続くリスト全体を返します。要素が1つだけのリストの場合は、リストの終端であるnilが返り値となります。
(cdr (list A)) ; → nil

cdrがnilを返せば、リストの終端と判断することができます。
また、与えられたリストが空(nil)であっても、cdrを使うことは可能。carと同様にnilを返すので、条件分岐や再帰処理で役立ちます。
(cdr nil) ; → nil
cdrはリスト(ドット対)を対象として関数なので、数値や文字列などリスト以外の値を与えるとエラーになります。
(cdr 100) ; エラー
(cdr "abc") ; エラー

安全に使いたいときは、listp関数などでリストかどうかを事前にチェックしてください。
cdrはリストを分解したり、要素を順に処理したりする場面でよく使われます。シンプルな関数ですが、リスト構造を理解するカギになるので、基本をしっかりおさえておきましょう。
任意の要素を取り出そう!carとcdrの組み合わせ関数一覧
リストから要素を取り出すときは、前述したcarとcdrを使うのが基本です。しかし、2番目や3番目の要素を取り出したいとき、carとcdrを何度も書くことになるのでプログラムが読みづらくなりがち。
そこで、AutoLISPにはcarとcdrを組み合わせて、1つにした関数が用意されています。たとえば、次のようなリストがあるとします。
(setq lst (list (list A B) (list C D) (list E F)))
以下のように書くと、2番目の要素である(C D)を取り出すことが可能。
(cadr lst) ; → (C D)
cadrは (car (cdr lst)) を短く書いたものです。「リストの先頭を1つスキップ(cdr)、次の要素を取り出す(car)」という意味になります。
さらに、2番目の要素から「C」を取り出す場合は次のように書いてください。
(caadr lst) ; → C

取り出したい要素がどこにあるか、確認しておくことが重要です。
carとcdrの組み合わせ関数一覧
AutoLISPに用意されているcarとcdrを組み合わせた関数は以下のとおりです。4段階の深さまでしか用意されていないので、5段階以上の要素を取り出したいときはnthを使ってください。
nthはリストからn番目の要素を取り出すAutoLISP関数です。nthについてはこちらの記事で解説しています。
>>【AutoLISP】リストの要素を取得する関数「nth」「last」「assoc」
関数 | carとcdrでの表記 |
caar | (car (car lst)) |
cdar | (cdr (car lst)) |
cadr | (car (cdr lst)) |
cddr | (cdr (cdr lst)) |
関数 | carとcdrでの表記 |
caaar | (car (car (car lst))) |
cdaar | (cdr (car (car lst))) |
cadar | (car (cdr (car lst))) |
cddar | (cdr (cdr (car lst))) |
caadr | (car (car (cdr lst))) |
cdadr | (cdr (car (cdr lst))) |
caddr | (car (cdr (cdr lst))) |
cdddr | (cdr (cdr (cdr lst))) |
関数 | carとcdrでの表記 |
caaaar | (car (car (car (car lst)))) |
cdaaar | (cdr (car (car (car lst)))) |
cadaar | (car (cdr (car (car lst)))) |
cddaar | (cdr (cdr (car (car lst)))) |
caadar | (car (car (cdr (car lst)))) |
cdadar | (cdr (car (cdr (car lst)))) |
caddar | (car (cdr (cdr (car lst)))) |
cdddar | (cdr (cdr (cdr (car lst)))) |
関数 | carとcdrでの表記 |
caaadr | (car (car (car (cdr lst)))) |
cdaadr | (cdr (car (car (cdr lst)))) |
cadadr | (car (cdr (car (cdr lst)))) |
cddadr | (cdr (cdr (car (cdr lst)))) |
caaddr | (car (car (cdr (cdr lst)))) |
cdaddr | (cdr (car (cdr (cdr lst)))) |
cadddr | (car (cdr (cdr (cdr lst)))) |
cddddr | (cdr (cdr (cdr (cdr lst)))) |

深い要素を取り出す場合はcarとcdrの組み合わせを使うより、nthの方がシンプルでわかりやすいのでおすすめです。
carとcdrを覚えてリスト操作の基本をマスターしよう!

今回の内容を以下にまとめます。
- AutoLISPのリストは「先頭の要素」と「残りの要素」の2つで構成されている
- 「先頭の要素」を「car」、「残りの要素」を「cdr」と呼ぶ
- carはリストのcar部を、cdrはcdr部を取り出すAutoLISP関数
- AutoLISPにはcarとcdrを組み合わせて1つにした関数が用意されている
関数 | 内容 | 使用例 |
car | リストの先頭要素を取り出す | (car (list 1 2 3)) ; → 1 |
cdr | リストの先頭要素以外を取り出す | (cdr (list 1 2 3)) ; → (2 3) |
carやcdrを使えばリスト操作が効率化されます。cadrなども活用すれば処理がよりスマートに。作図の自動化や業務効率化にもつながるので、ぜひ実務で役立ててください。