Python入門(2) printと入力、数の計算、文字列

printの改行問題

地味な話であるが、出力 print まわりはどのプログラミング言語でも取り扱いは複雑である(それだけ、印刷物に対する我々の感覚は鋭いわけだ)。 Python2ではprintはprint文であったものが、python3ではprint関数となって取り扱いが首尾一貫した結果、なかなかpython2とpython3とのすり合わせが難しくなった。

Python2でのprint文は原則括弧 ( ) で囲むことはしないのだが、print文を実行すると末尾で改行される(次のprint文の先頭文字列は次行の先頭にセットされる)。 Python3でもprint関数を実行して出力(変数や値の並び)を終えると改行される。 つまり、Python2もPython3でも、デフォルトではprintを実行すると、表示文字列の末尾に改行文字new line\n が付与されて出力され、結果改行される。

改行しないprint

Python2ではprint文の最後にコンマ(,)を追加すると改行文字は半角スペースに置き換えられて改行されない。 次のPython2スクリプトの結果を比較して欲しい。 改行されないようにしたとき、Hello と world の間に半角空白が挿入されていることがポイントだ。

# 改行されるprint文
print 'Hello'
print 'world'

# printy文の最後にコンマを追加
print 'Hello',
print 'world'
演習: 上のPython2スクリプトを実行してprint文の改行の有無を確かめなさい。

一方、Python3では、print関数において、オプションend = ''を追加すると改行されない(ここで「''」は空文字列(引用符の間には文字がない)である)。 次のPython3スクリプトの結果を比較して欲しい。 改行されないようにしたとき、Hello と world の間には空文字であることがポイントだ。

# 改行されるprint
print('Hello')
print('world')

# printy内で end = '' を追加
print('Hello', end = '')
print('world')

print関数内でendにセットする文字を変化させてみてほしい。

# printy内で end = '' を追加
print('Hello', end = '')
print('world')
 
# printy内で end = ' ' を追加(半角空白が引用負(')で挟まれている)
print('Hello', end = ' ')
print('world')
演習: 上のPython3スクリプトを(Python3環境で)実行してprint結果を検討しなさい。

print並びの区切り文字

以下はPython3のprint関数の説明である。

Python3のprint関数の他のオプションも必要になることがある。 printのオプション sep は区切り文字指定で、print関数内でカンマ(,)で区切って並べられて出力される文字列表記の間の区切り文字列を設定する。 デフォルトは半角空白であるが、以下のようにこれを変更することができる。

print('Hello', 'world')
 
# printy内で sep を変更
print('Hello', 'world', sep =',')
print('Hello', 'world', sep =', ')# 引用符(')の間に『カンマ(,)と半角空白』がある
演習: 上のPython3スクリプトを(Python3環境で)実行してprint結果を検討しなさい。

Python3のprint関数のオプションは同時に指定できる。

print('Hello', 'world', sep =",", end = "")
演習: Python3環境でこうしたprint関数のオプションを変更しながら、適切なスクリプトを書いてみなさい。

ユーザーからの入力

以下はPython3のprint関数の説明である。

Pythonスクリプト実行しながら、ユーザからの入力が利用できると楽しい。 このために用意された関数がinput(python3)だ。 まず、使い方を知ろう。

# キー入力した文字列の形(type)とその内容を出力
st = input('Input : ')
print(type(st))
print('Your input = ', st)

これを実行すると、次のように input( ) 内で指定された文字列が表示されて実行が一旦停止されキーボードからの文字列入力を待ち、それが変数 st に格納され、print文でその変数データの形(type)を出力し、さらに変数内容をプリントする。 ここでは、入力文字列は Hello とし、次いでEnterを押して文字列入力を終えている。

キー入力を数字として扱う

Python3の input() によるキーボード入力は、上の実行結果からわかるように、文字列として取り扱われている。 実際、次の実行結果を得る(<class 'str'>に注意)。

Input : 3.1415              ← 3.1415 のキー入力してReturnキーを押す
<class 'str'>
Your input = 3.1415           

『数に見える』ような数字文字列を数データに変更することができる。

整数文字列を整数(integer: 小数点がない)として取り扱うためにはint関数で、小数点付き文字列を浮動小数(float: 小数点がある。実数(real)ともいう)として取り扱うためにはfloat関数で変換する。

# キー入力した2つの数字を足す
n = int(input('Input an integer n = '))
x = float(input('Input a float x = '))
print('Your input n = ', n)
print('Your input x = ', x)
print('n + x = ', n + x)

1,2行目でそれぞれ int や float にキャスとしている。 実行結果はたとえば、次のようになる。

Input an integer n = 25      文字列『25』をキー入力
Input a float x = 3.1415     文字列『3.1415』をキー入力
Your input n = 25, 
Your input x = 3.1415
n + x = 28.1415

変数の「型変換」を一般にキャスト(cast)という。 int() や float() 以外に、数値(整数や浮動小数)を文字列に変換する関数 str( ) がある。

演習: スクリプト input_numbers.py を実行して、整数文字列であるキー入力に浮動小数点文字列を入力するとどうなるかを確かめなさい。
演習(重要): 整数文字列であるべきキー入力に浮動小数点文字列を入力しても、スクリプト内の計算で整数として計算してくれるよう、 input_numbers.py を柔軟なスクリプトに改良し、実行してその様子を確かめてみなさい。 (ヒント)int関数は整数文字列を整数に変換するだけでなく、浮動小数を整数に変換することができる(整数キャスト)。int(12.7) や int (-3.2) は 0 に近い整数に値が丸められる。

キーボード入力によってプログラミング結果を確認できることは、次のような同じようなスクリプトよりも明らかに楽しいはずだ。 ここでは、固定的に変数 x には整数 25 が、変数 y には浮動小数点 3.1415 が割り当てられている。

# 2つの数を足す
ix = 25
y = 3.1415

print('my setting n, x = ', n, x)
print('n + x = ', n + x)

数の計算

Python を電卓代わりに使うことができる。 割り算 / の取り扱いがPython2とPython3とで違っていることに注意しよう。

演算子意味計算式計算結果
+2項の和2.4 + 57.4
-2項の差2.4 - 5-3.4
*2項の積2.4 * 512.0
/2項の商2.4 / 50.48
python2での整数商12 / 52
python3での整数商12 / 52.4
//python3の商12 // 52.0
python3の商12.4 // 52.0
%整数商の剰余12 % 52
12 % -5-3
-12 % 53
**整数べき乗3 * 327
2.4 * 37.199999999999999
( )優先計算(4 + 3) * 535

注意:乗算のために記号であるアスタリスク (*) 可変長引数を指定する場合にも使われる。

Python2でキー入力した「数」について、次のようなスクリプトが可能である。

# キー入力した数の計算
n = int(input('Input an integer : '))
y = float(input('Input a float : '))

print(n, ' + ', y, ' => ', n + y)
print(n, ' - ', y, ' => ', n - y)
print(n, ' * ', y, ' => ', n * y)
print(n, ' / ', y, ' => ', n / y)
print(y, ' ** ', n, ' => ', y ** y)

m = int(input('Input another integer : '))

print(m, ' % ', n, ' => ', m % n)
演習: 上のスクリプトを実行しなさい。
同様にinput関数を使って、2つの整数 ix, iy や、2つの浮動少数 x, y との四則演算 + - * /(//) を計算するスクリプト compute.py を書いて実行してみなさい。
四則演算の整数同士、浮動小数同士との計算の差異を理解し、数の自在な計算を書くにすることがポイント。

基数変換

整数文字列を整数にキャストする関数 int では、第2引数にその整数を表している基数(radix)を指定して、10進数に変換することができる。

たとえば、0と1からなる文字を使った文字列を基数2の2進数(binary number)であるとみなし、それを10進数(decimal number)に変換できる。 また、0,1,2,3,4,5,6,7からなる文字を使った文字列を基数8の8進数(octal number)であるとみなし、それを10進数に変換できる。 あるいは、0,1,2,3,4,5,6,7,8,9,9,A,B,C,D,F(A〜Fは小文字でもよい)までの文字を使った文字列を基数16の16進数(hexadecimal number)であるとみなし、それを10進数に変換できる。
次の例を丁寧に観察しよう。

>> int("1001", 2)
9
>>> int("123", 8)
83
>>> int("AFF0", 16)
45040

コンピュータの世界では、10進数以外にもしばしば2進数、8進数、16進数がが使われる。 2進数であることを明示するために 0b を左端につけて 0b1001、8進数であることを明示するために 0o を左端につけて 0o123、16進数であることを明示するために 0x を左端につけて 0xAFF0 などと表記する。

実際、スクリプト内で次のよう書くことが可能である。 変数 x には2進数、y には8進数、 z には16進数が割り当てられている。

x = 0b1001
y = 0o123
z = 0xaff0
print(x, y, z)
print(x + y + z)
演習: 上のスクリプト radix.py を実行しなさい。
演習: キーボードから入力した10進数、2進数、8進数、16進数の整数同士の四則演算を行うスクリプト radix.py を書いて実行しなさい。

文字列の連接

文字列についての演算が定義される。 もっとも多用されるのが文字列の連接(concatenattion)で、2つの文字列を並べて新たに文字列とする操作である。 文字列の連接は記号 + で実行できる。

>> print('Hello' +'world')
Helloworld

これは次のように書いても同じことはPython shellですぐに確かめられる。

>>> h = 'Hello'
>>> w = 'world'
>>> print(h + w)
Helloworld

しかし次はうまくいかない。

'Hello' + 21
SyntaxError: invalid syntax
演習: 上のスクリプトが失敗する理由を説明し、実行結果 Hello21 となるように改めなさい。 (ヒント):数を文字列にキャストする。

重要:変数値の上書き

変数 h と w にあり当てた文字列について、h と w を連接 h + w して、その値を再び h に割り当てた時には、以前に格納されていた値は上書き(over write)されてしまうことに注意する。 このことは不都合に思われるかもしれないが、この性質を利用して効率のよく分かりやすいプログラミングが可能になる。

>>> h = 'Hello'
>>> w = 'world'
>>> h = h + w
>>> h
'Helloworld'
>>> w
'world'

文字列の長さ

文字列の長さは関数 len を使って取得できる。

h = 'Hello'
w = 'world'
print(h + w, ' has a length ', len(h + w))
演習: 上のスクリプトを実行したり、さまざまに改良してみなさい。
演習: 上の string_length.py において、Python3で次のようにして日本語文字列に変更してみた。 ただし、スクリプトファイルは文字符号化 UTF-8 で保存してあるとする(絶対的な前提である) スクリプトを実行した時に「正しく」表示されるだろうか。 文字列表示が正常か、文字数のカウント結果が正しいかの2点がポイントである。
h = '世界は'
w = '広い'
print(h + w, ' has a length ', len(h + w))

Pythonの文字列単位

Pythonでは,文字列は8ビット単位で格納され,その文字符号化はプラットフォームによって異なる。 Python3でただしく文字単位を処理を行う場合には,取り扱われる文字データはUnicode文字列(に変換する)である必要がある.

演習: スクリプトファイルstring_length.pyを文字符号化 UTF-8で保存して、 さまざまな文字処理を行ってみなさい。 なにか差し障りがないかどうかを確かめなさい。