型と演算子

Pythonプログラムの構造

  1. プログラムはモジュールから構成される
  2. モジュールは文のならび
  3. 文はオブジェクトを生成し,処理する

組み込み型

整数・ロング整数・浮動少数・複素数 数値定数では 10進,8進,16進数表現がある

組み込みツール

演算子と優先順位

演算子説明
X or y, lambda引数:式論理和,無名関数
X and y 論理積
not x 論理否定
<, <=, >, >=, ==, <>, !=,
is, is not,
in, not in
比較,
同一性,
メンバシップテスト
x | y ビット毎の論理和
x & y ビット毎の論理積
x << y, x >> y xを左または右へyビットシフト
x + y, x - y 加算/連結 減算
x * y, x / y, x % y 乗算/繰り返し, 除算,剰余/書式
-x, +x, ~x 単項の符号反転,等価,ビット毎の反転
x[i], x[i:j], x.y, x(...) 添字付け,スライス,修飾,関数呼び出し
(...), [...], {...}, `...`タプル,リスト,ディクショナリ,文字列への変換

数値演算の実例

>>> a = 3
>>> b = 4
>>> b / 2 + a
5
>>> b / (2.0 + a)
0.80000000000000004
>>> x = 1
>>> x << 2
4
>>> x | 2
3
>>> x & 1
1
>>> 9999999999999999 + 1
OverflowError: integer literal too large
>>> 9999999999999999L + 1
10000000000000000L
>>> 1j * 1J
(-1+0j)
>>> 2 + 1j * 3
(2+3j)
>>> (2 + 1j) * 3
(6+3j)
>>> import math
>>> math.pi
3.1415926535897931
>>> sin(2*pi)
Traceback (innermost last):
  File "", line 1, in ?
    sin(2*pi)
NameError: There is no variable named 'sin'
>>> math.sin(2*math.pi)
-2.4492127076447545e-016
>>> from math import *
>>> sin(2*pi)
-2.4492127076447545e-016
>>> abs(-42), 2**4, pow(2, 4)
(42, 16, 16.0)
>>>

文字列

文字列定数と操作
操作解釈
s1 = '' 空文字列
s2 = "spam's" ダブルクォート
block = """..."""トリプルクォートブロック
s1 + s1,
s2 * 3
連結,
反復
s2[i],
s2[i:j],
len(s2)
添え字付け,
スライス
長さ
"a %s parrot" % 'dead' 文字列書式
for x in s2,
'm' in s2
繰り返し,
メンバシップ

文字列演算の実例

>>> len('abc')
3
>>> 'abc' + 'def'
'abcdef'
>>> 'Ni!' * 4
'Ni!Ni!Ni!Ni!'
>>> myjob = "hacker"
>>> for c in myjob: print c,

h a c k e r
>>> "k" in myjob
1
>>> S = 'spam'
>>> S[0], S[-2]
('s', 'a')
>>> S[1:3], S[1:], S[:-1]
('pa', 'pam', 'spa')
>>> S[0] = 'x'
Traceback (innermost last):
  File "", line 1, in ?
    S[0] = 'x'
TypeError: object doesn't support item assignment
>>> S = 'x' + S[1:]
>>> S
'xpam'
>>> S = 'spam'
>>> S = S + 'Spam!'
>>> S
'spamSpam!'
>>> S = S[:4] + 'Burger' + S[-1]
>>> S
'spamBurger!'
>>> 'That is %d %s bird!' % (1, 'dead')
'That is 1 dead bird!'
文字列整形変換指令(詳しくは man printf)
%s 文字列
%c 文字
%d 10進数(整数)
%i 整数
%u 符号無し(整数)
%o 8進整数
%x 16進整数
%X 16進整数(大文字)
%e,%E 浮動少数(例1.25e-5)
%f 少数(0.0000125)
%g,%G 浮動少数
%% %

文字列に対するツール

string, __bultins__.str, re, ...
>>> import string
>>> S = 'spammify'
>>> string.upper(S)
'SPAMMIFY'
>>> string.find(S,'mm')
3
>>> string.atoi('42'), `42`
(42, '42')
>>> string.join(string.split(S, 'mm'), 'XX')
'spaXXify'
>>> S.upper()
'SPAMMIFY'
>>> S.find('mm')
3
>>> import re
>>> re.split('mm',S)
['spa', 'ify']
>>> re.sub('mm','XX',S)
'spaXXify'
>>> string.sub('mm','XX',S)
バックスラッシュ(\) によるエスケープ
\改行 行の継続
\\ バックスラッシュ
\' シングルクオート
\" ダブルクオート
\a ベル
\b バックスペース
\000 null
\n 改行
\v 垂直タブ
\t 水平タブ
\r 復帰(キャリジリターン)
\f 改ページ
\0XX 8進コード XX
\xXX 16進コード XX
\(その他)そのまま
>>> big = """This is
a multi-line block
of text; Python puts
an end-of-line marker
after each line."""
>>> big
'This is\012a multi-line block\012of text; Python puts\012an end-of-line marker\012after each line.'
>>> print big
This is
a multi-line block
of text; Python puts
an end-of-line marker
after each line.

リスト

Python のリストは
>>> L1 = []
>>> L2 = [0, 1, 2, 3]
>>> L3 = ['abc', ['def', 'ghi']]
>>> L2[2]
2
>>> L3[1][1]
'ghi'
>>> len(L2)
4
>>> for x in L2:
	print x,
	(改行)
	
0 1 2 3
>>> L2.append(4)
>>> L2
[0, 1, 2, 3, 4]
>>> L2.reverse()
>>> L2
[4, 3, 2, 1, 0]
>>> L2.sort()
>>> L2
[0, 1, 2, 3, 4]

ディクショナリ

>>> d1 = {}
>>> d2 = {'spam': 2, 'eggs': 3}
>>> d2['spam']
2
>>> d3 = {'food': {'ham': 1, 'egg': 2}}
>>> d3['food']['egg']
2
>>> d2.has_key('eggs')
1
>>> d2.has_key('ham')
0
>>> d2.keys()
['spam', 'eggs']
>>> d2.values()
[2, 3]

タプル

「更新不能」であることを除けばリストとほぼ同じ.

ファイル

>>> myfile = open('myfile','w')
>>> myfile.write('hello text file\n')
>>> myfile.close()
>>> mf = open('myfile','r')
>>> mf.readline()
'hello text file\012'
>>> mf.readline()
''

オブジェクトの一般的性質

型カテゴリ

オブジェクト型カテゴリ更新可能性
数値 No
文字列 シーケンス No
リスト シーケンス Yes
ディクショナリ写像型 Yes
タプル シーケンス No
ファイル 拡張 適用不能

一般性

共有レファレンス

>>> X = [1, 2, 3]
>>> L = ['a', X, 'b']
>>> D = {'x':X, 'y':2}
>>> X
[1, 2, 3]
>>> L
['a', [1, 2, 3], 'b']
>>> D
{'x': [1, 2, 3], 'y': 2}
>>> X[1] = 'surprise'
>>> X
[1, 'surprise', 3]
>>> L
['a', [1, 'surprise', 3], 'b']
>>> D
{'x': [1, 'surprise', 3], 'y': 2}

大小比較,等値性 および 真偽

== 演算子は 同値性をテストする
is 演算子は オブジェクトの同一性をテストする

型の階層性

組み込み型の落とし穴

演習問題

  1. Python を起動し,対話的に以下の式を入力し,その結果について説明しなさい.
    2 ** 16
    2 / 5, 2 / 5.0
    
    "spam" + "eggs"
    S = "ham"
    "eggs " + S
    S * 5
    S[:0]
    "green %s and %s" % ("eggs", S)
    
    ('x',)[0]
    ('x', 'y')[1]
    
    L = [1,2,3] + [4,5,6]
    L, L[:], L[:0], L[-2], L[-2:]
    ([1,2,3] + [4,5,6])[2:4]
    [L[2], L[3]]
    L.reverse(); L
    L.sort(); L
    L.index(4)
    
    {'a':1, 'b':2}['b']
    D = {'x':1, 'y':2, 'z':3}
    D['w'] = 0
    D['x'] + D['w']
    D[(1,2,3)] = 4
    D.keys(), D.values(), D.has_key((1,2,3))
    
    [[]], ["",[],(),{},None]
    	
  2. 次のようなタプルを使った代入を試してみよう.
    x = 'spam'
    y = 'eggs'
    x, y = y, x
    print x, y
    
    このような結果(交換)を実現するために,Cや Pascal ではどのように書かなければならないか,思い出してみよう.
  3. 以下の例を参考に,「自分」を表すデータ構造を作成しなさい.
    >>> me = { 'name': {'first': 'Tokio', 'last': 'Kikuchi'}, \
           'age': 50, 'email': 'tkikuchi@is.kochi-u.ac.jp'}
    >>> me
    {'email': 'tkikuchi@is.kochi-u.ac.jp', 'age': 50, 'name': {'first': 'Tokio', 'last': 'Kikuchi'}}
    >>> me['name']
    {'first': 'Tokio', 'last': 'Kikuchi'}
    >>> me['email']
    'tkikuchi@is.kochi-u.ac.jp'
    >>> me['name']['first'] , me['name']['last']
    ('Tokio', 'Kikuchi')
    
  4. myfile.txt という名の出力ファイルを新規に作成し,それに文字列 "Hello file world!" を書きこむような スクリプトを書きなさい.次に,myfile.txt をオープンしてその内容を読み出して表示するような, 別のスクリプトを書きなさい.これらの2つのスクリプトを UNIX のコマンドライン から実行し,新しいファイルが作成されることを確認しなさい.