第4回の記事からはプログラミングに必要な知識について詳細に学んでいきます。今回はまず、プログラミングの基礎である「型」と「変数」という概念について解説していきます。

プログラミングで使われるデータには「型」と呼ばれるものがあります。たとえば、1や2というのは「数値」という型で、“Hello”というテキストは「文字列」という型です。プログラミングをする際に、初心者の方はこの「型」について意識することが重要です。なぜかというと、「型」と「処理」は密接に結びついているためです。

例をあげて説明してみます。Python のプロンプトを立ち上げて以下を実行してみてください。

>>> 3 + 3
6
>>> 3 - 1
2

上記のように数値は足し算、引き算することができます。当たり前といえば当たり前ですね。

では、文字列はどうでしょうか。文字列は ' ' でアルファベットや記号を囲むことで作成できますので、先ほどと同じように足し算と引き算をさせてみます。

>>> 'hello' + 'python'
'hellopython'
>>> 'hello' - 'python'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for -: 'str' and 'str'

文字列の足し算はできました。文字列の後ろに別の文字列をくっつけるという「結合」処理がされています。文字列の結合は数値の足し算とは違いますが、これも直感的な処理内容といえるのではないでしょうか。

ただ、文字列の引き算をしようとしたところ、エラーが表示されてしまいました。このエラーの内容は「operand(オペランド)」という言葉で小難しく説明されていますが、要するに「文字列 - 文字列」という処理はできないということを言っています。

最初にも説明しましたが、「型」と「処理」は密接に結びついています。数値だったら足し算も引き算もできますが、文字列は足し算(結合)しかできません。同様に文字列でしかできない処理というのも存在しています。すべてを暗記する必要はありませんが「どの型がどのような処理をすることができるか」「その処理をするにはどういう書き方をすればいいか」ということをある程度知っておくことは重要です。これはほかの言語でも使える知識なので、決して無駄にはなりません。

数値(型)と文字列(型)

なお、ぱっと見て同じように見えるデータであっても、型が違えば別物ですので注意が必要です。例えば数値の3と文字列の'3'は別物です。前者は引き算に使えますが、後者は使えません。後者はあくまでも文字列としての3であり、数値ではありません。

変数

型の続きを説明する前に変数の話をしてしまいましょう。変数はデータを格納するための箱のようなものです。プログラミングは1行1行に命令を書き連ねていくことで実現されますが、後ろの行で前の行の結果を利用する場面などが必ずあります。そのような場合に、変数に命令の結果を保存して、それを後で使うといった利用方法がとられます。イメージとしては以下の図のようなものとなります。

「変数」のイメージ

変数の使い方は非常に簡単で、以下のように

変数名 = 変数に入れたい値

と宣言するだけで、変数に値が格納されます。変数名はアルファベットから始まる「特別なキーワード」を避ければ、好きなものを使ってかまいません。特別なキーワードとは、これからの連載で扱う「Pythonの文法」で利用されるものです。たとえば、条件分岐のifやelseなどは変数名には使えません。なお、変数に値を入れることを「代入する」といいますので、覚えておいてください。

変数が利用される場合は、その中に実際に代入されている値が自動的に取り出されて使われます。以下に例を示します。

>>> a = 5
>>> print(a)
5
>>> b = a + 5
>>> print(b)
10
>>> b = a + 6
>>> print(b)
11

取り出しただけではデータは消失しないので、何度でも利用できます。たとえば変数aに5を代入した後に、変数aから2回値を取り出していますが、2回とも5が取り出されています。一般的には、取り出すというよりも“変数aが5を「返す」”というような言い方をします。

ただ、注意してほしいのは「なにか値が代入されている変数」に新しい値を代入してしまうと「昔の値」は上書きされてしまうということです。上記例で、bは10を保持していましたが、そこに11が代入されると10を消失してしまいます。また、代入されていない変数を使おうとするとエラーとなります。

少し高度になりますが、変数に同じ変数の値を加工して代入することも可能です。たとえば、変数aにすでに文字列が入っており、それに別の文字列を追加したいという場合は以下のように書きます。

>>> a = 'hello'
>>> a = a + 'python'
>>> print(a)
hellopython

上記の「a = a + 'python'」は

  1. 右のaが'hello'という文字列を返す
  2. それに'python'が結合されて'hellopython'になる
  3. 'hellopython'が左のaに代入される

という意味になります。それほど難しくはないですね。なお、「a = a」のように加工せずにそのまま代入することもできますが、その処理にとくに意味はありませんので普通はしません。

以上のように、Pythonの変数の概念は非常に簡単です。「変数はどのような型の値でも格納する入れ物のようなもの」ということを理解していれば、しばらくは何も問題ありません。ただ、CやJavaなどのほかの言語だと、変数の概念はもう少し複雑なので、次のセクションではその話をします。興味がない人は読み飛ばしていただいてかまいません。

変数と型

Python以外の言語を少しでも学んだことのある人は、先ほどのPythonの変数の使い方に違和感を覚えられたかもしれません。CやJavaなどは「変数」と「型」が密接に結びついています。具体的にいうと変数にも型があり、変数の型と代入する値の型は同一である必要があります。

たとえば、Javaで変数xを宣言し、それを利用するには以下のように書きます。

// JAVA
int x;
x = 5;         // OK
x = "Java"     // Error

Pythonで変数を利用する場合、変数xの前に「int」というキーワードは存在していませんでした。intは整数型のことなので、この場合は「整数型の変数x」を作っています。Javaの変数には必ず型があるので、変数を宣言する(作る)際には必ず「int」といった型を示す必要があります。

上記例では変数を作成した後で、その変数に整数値5と文字列“Java”を代入しています。変数xは整数型なので、同じ整数型である5は代入できるものの、文字列型の“Java”は代入できずにエラーとなります。

文字列型の変数もこれと同じです。文字列を格納するために作成された変数yに文字列を代入することは当然できますが、整数型である5を代入することはできません。

// JAVA
String y = "Java";   // OK
y = 5;               // Error

一方、Pythonの変数にはどのような型でもいれることができるので、以下のように「整数を代入した変数に文字列を代入する」ことも、問題ありません。そもそもJavaでいう「int」や「String」といった変数の型宣言がPythonのコードにはありませんね。

# PYTHON
x = 5
x = 'python'

Python と Java の変数の使い方の違いを図にまとめます。

PythonとJavaの変数

ただ、上記のような「変数を使いまわす」ようなコードは一般的には避けたほうがよいです。一度宣言された変数を「別の使い方で再利用」すると、その変数に何が入っているのかわかりにくくなるため、プログラミングの行儀がよくありません。専門的な言い方をすると「保守しにくいコード」といわれます。まぁ、脱線はこのぐらいにして本題に戻りましょうか。

Python の型の種類

型と変数の基本的な使い方がわかったので、最初に知るべき重要な型とその利用法をいくつか紹介したいと思います。今回紹介するのは以下の4つとなります。

  • 数値
  • 文字列
  • Bool(ブール)
  • リスト(配列)

この4つの型を使わずにプログラムを書くことは不可能と言ってもよいほどです。これ以外にも重要な型はいくつかありますが、まずはこれら4つの型をしっかりと使いこなせるようになることが大事です。

数値型と演算子

いくつかのプログラミング言語では、同じ数値といっても、それが種類ごとに細かく分類されて別の型として扱われます。たとえば、CやJavaでは「整数」と「小数」は別物ですし、それらも表現できる上限値が決まっています。

Javaの整数型であるintは32bitで整数を表現する型であるため、小数点は扱えない(切り捨て)ですし、32bitで表現できない非常に大きな数なども利用できません。一方、Pythonで数値を使うのは非常に簡単です。正確には、整数型や小数型は存在するものの、それらは同じ「数値型」のようなイメージで扱うことができます。

たとえばJavaのintで表現できない非常に大きな桁も、特別な操作をせずに表現できます。

>>> 123456789 * 123456789
15241578750190521

では、数値型でどのような処理ができるかという話に移りましょう。とくに断りなく使ってきましたが、数と数の計算に使用する「+」や「-」といった記号は「演算子」とよばれています。そして演算子の演算対象となる値を「オペランド」と呼びます。たとえば、1 + 2の演算子は「+」であり、そのオペランドは「1」と「2」です。数値型に関しては、この演算子の種類を知ることが「処理」を知ることの第一歩といえます。

Pythonの数値計算で利用可能な演算子は以下となります。いくつかは算数で使われる記号なのでわかりやすいですが、プログラミング独自の記号の使い方や、Pythonだけでしか使えない記号もあります。足し算、引き算、掛け算、割り算がメインとなる処理ですが、ほかの演算もときどき使うので覚えてしまってもいいかもしれません。

利用可能な演算子 説明
M + N 足し算
M - N 引き算
M * N 掛け算
M / N 割り算
M % N 剰余(あまり)
M ** N べき乗(M * M * M.. を N回)

算数の授業で習ったかと思いますが、演算子にも優先順位があります。たとえば算数で「1 + 2 x 3」という計算をする場合、足し算よりも掛け算が優先されるため、1+2よりも先に2x3が計算されて、答えは7になりますよね。Pythonでも同様に、上記の計算結果は7となります。掛け算よりも足し算を優先する場合は「足し算を()で囲む」ことをしますが、Pythonも同様です。

>>> 1 + 2 * 3
7
>>> (1 + 2) * 3
9

とりあえず数値型の処理の紹介はこれで終わりです。ただ、当然ながらほかにも多くの処理が存在しています。たとえば今までも利用していた「絶対値を得る方法」や、「文字列の数字を数値型に変換する方法」などもあります。よく行われる処理は調べればすぐわかるので、その都度ドキュメントをあたるなり、検索エンジンを使うなりして解決してください。

数値型と代入演算子

演算子の話をしたので、次に代入を行うための特別な演算子である「代入演算子」の紹介もします。名前からわかると思いますが、代入と演算を同時に行うのが代入演算子です。

利用可能な演算子 説明
M += N M = M + N
M -= N M = M - N
M *= N M = M * N
M /= N M = M / N
M %= N M = M % N
M **= N M = M ** N

演算子と代入の記号(=)がくっついているだけなので、規則性は見てとれますね。

注意すべきなのは、PythonにはCやJavaでいうインクリメント/デクリメントが存在しないことです。インクリメントは変数の値に1を加えることで、そのためには特別な演算子である「++」を使います。

たとえばJavaの以下のコード

int i=0;
i++;

では、i は 1 になります。Pythonで同様のことを行うには、以下のように書きます。

i = 0
i += 1

変数iに1を加えた値を、再度iに代入することは、インクリメントすることと実質的に同じです。デクリメントも同じように使います。

関数による数値の操作

演算子と代入演算子以外にも、数値を操作する方法があります。特定の関数に数値を与えることで、新しい数値を得ることができます。たとえば絶対値を得たり、べき乗の値を得たり……

# -5 の絶対値
>>> abs(-5)
5

# 2 の 8 乗
>>> pow(2, 8)
256

数値の操作はさまざまな処理で利用されます。たとえば解析ツールや統計処理を行うアプリケーションを作るのであれば、数学的な処理をする必要があります。

演算子と数学的知識を使って、それを自力で実装する方法もありますが、可能であれば実装の労力と実効速度およびバグの少なさを考慮して「標準ライブラリ」や「外部のライブラリ」を使うべきです。


演習1

以下の図形の面積を求めて下さい。

  1. 変数に領域 a,b,c の値をそれぞれ変数に代入してから、その面積の合計値を求める
  2. 変数を使わないで領域 a,b,c の合計の面積を求める

演習2

まだ説明していない組み込み関数を利用して、以下の問題をクリアしてください。公式のドキュメントから関数を探す、検索エンジンを利用するなど手段は問いません。

  1. 文字列 '123'を整数の123に変換する
  2. 文字列 '123.4'を小数の123.4に変換する

※解答はこちらをご覧ください。


さて次回は、今回の続きです。文字列型、Bool型、リスト型について取り扱います。

執筆者紹介

伊藤裕一(ITO Yuichi)

シスコシステムズでの業務と大学での研究活動でコンピュータネットワークに6年関わる。専門はL2/L3 Switching とデータセンター関連技術およびSDN。TACとしてシスコ顧客のテクニカルサポート業務に従事。社内向けのソフトウェア関連のトレーニングおよびデータセンタとSDN関係の外部講演なども行う。

もともと仮想ネットワーク関連技術の研究開発に従事していたこともあり、ネットワークだけでなくプログラミングやLinux関連技術にも精通。Cisco社内外向けのトラブルシューティングツールの開発や、趣味で音声合成処理のアプリケーションやサービスを開発。

Cisco CCIE R&S, Red Hat Certified Engineer, Oracle Java Gold,2009年度 IPA 未踏プロジェクト採択

詳細(英語)はこちら