「大人の教養・知識・気付き」を伸ばすブログ

一流の大人(ビジネスマン、政治家、リーダー…)として知っておきたい、教養・社会動向を意外なところから取り上げ学ぶことで“気付く力”を伸ばすブログです。目下、データ分析・語学に力点を置いています。

MENU

Pythonで学ぶアルゴリズム(01/18)

 アルゴリズムを学ぶのにPythonの学習も兼ねて

を参照していく。

1. Python入門

1.1 文法の基礎

 \mathrm{Python}の文法をまとめる。

1.1.1 数と文字列
type(2)

 数の表記の仕方でデータ型を区別することができる。これをリテラルという。
 以下のような基本的な演算がある。

### 加減乗除:
# 整数と整数の四則演算は、除算を除き整数になる
print(1 + 1)
print(2 - 1)
print(3 * 4)
print(4 / 2)
print(4 // 2) # 商を返す
print(4 % 2)  # 余りを返す

# 文字列は引用符'または"で囲む。開始と終了で同じ記号を用いる
print(type(5))
print(type('5'))

ch = """
複数行の文字列は
3重の引用符で
囲むことができる
"""

print(ch)

 \\mathrm{n}は制御文字と呼ばれる特殊文字で改行を意味する。\mathrm{Python}\mathrm{Unicode(UTF-8)}として扱う。

 データ型は意識しなければならない。文字列同士は\mathrm{+}で連結できるものの、文字列と数値は連結できない

print('abc' + 'xyz')  # + で文字列同士を連結して新たな文字列にできる
print('abc' + str(4)) # str関数で4を文字列にしたら連結可能

# 文字列と数値は連結できない
try:
    'abc' + 4
except:
    print('文字列と数値は連結できません。')


1.1.2 変数と比較演算

 引用符が無い文字列と何らかのデータを演算子=で結合すると変数を定義できる。\mathrm{Python}では自動的に判定してくれるため、データ型を定義する必要はない。変数名はスネークケースと呼ばれる記法で書く:

  • 単語をすべて小文字で書く
  • 単語の区切りをアンダースコア(_)でつなげる

 一度定義した変数に別のデータ型を代入することもできる。演算と代入を同時にできる複合代入演算子もある。

 \mathrm{len}で文字列の長さを調べることができる。
 演算子\mathrm{==}で両辺が等しいかを調べることができる。等しくないことを知るには\mathrm{!=}とする。何もないことを表現するには\mathrm{None}を用いる。変数が\mathrm{None}か否かは\mathrm{is}を用いる。

# 変数の定義
my_variable = 23
print(my_variable)

# 既に定義された変数に新たな型の値を入れることもできる
my_variable = 'abc'
print(my_variable)

# 複合代入演算子
my_variable *= 3
print(my_variable)

# 文字列の長さを調べる
len(my_variable)

# 真偽型:==で両辺が等しいかを判断する
x = 5
print(x == 5) # 5に等しいか

print(x != 4) # 4に等しくないか

# is None:何もないことを意味するNoneなのかを判定するにはisを用いる
print(my_variable is not None) # 否定にはnotを付ける


1.1.3 コンテナデータ型

 データをまとめて扱えるデータ型をコンテナ型という。頻用されるには、リスト型、辞書型、タプル、セットがある。
 角括弧\mathrm{[]}の中に要素をカンマで並べて書くとリスト型のデータを作ることができる。慣例としてカンマの後には半角空欄を入れる。
 リストから要素を取り出すための添字は0から始める。
 リストには\mathrm{append}メソッドで要素を追加する。添字として負の値を指定すると、-1を最後の要素として先頭へ近づいていく。
 空のリストは\mathrm{[]}を書くか組み込み関数\mathrm{list}を引数無しで呼ぶ。
 すべての要素が同じで特定の長さのリストを作る場合は演算子\mathrm{*}を用いる。

##############
### リスト ###
##############
# リスト型の定義
my_list = [10, 20, 30]

# リスト型の添字は0から始まる
print(my_list[1]) # 10にはならない

# リスト型に要素を追加する
my_list.append(40)
print(my_list) # [10,20,30,40]と40が追加されている

# 添字として負の値を指定
print(my_list)[-1] # 最後の40が与えられる

# 同じ要素を持つ特定の長さのリストを与える
ten_zero_list = [0] * 10
print(ten_zero_list)

 辞書型はキーと値の組み合わせを保持するデータ型である。波括弧\mathrm{\{\}}でキーと値の組み合わせカンマ区切りで並べる。
 要素へのアクセスには角括弧を用いてキーを指定する。新たなキーと値のペアを既存の辞書型に追加するには角括弧を用いて定義する。辞書型では存在しないキーを指定するとエラーになる。空の辞書型は\{\}か組み込み関数\mathrm{dict}で定義する。

##############
### 辞書型 ###
##############
# 辞書型を定義する
my_dict = {'key1': 10, 'key2': 20, 'key3': 30}

# 辞書型の要素へのアクセス
print(my_dict['key1'])

# 辞書型に新たな要素を定義する
my_dict['key4'] = 40
print(my_dict['key4'])

# 存在しないキーを指定するとエラーになる
try:
    my_dict['key5']
except:
    print('存在しないキーを指定するとエラーが表示されます。')

# 空の辞書型を定義する
my_dict1 = {}
my_dict2 = dict()

print(my_dict1 ==my_dict2)

 タプルは変更できないリストに相当する。タプルを定義するには鍵括弧()を用いる。要素のアクセスには角括弧を用いる。
 タプルは変更できないものの辞書型のキーにすることができる。

##############
### タプル ###
##############

# タプルを定義する
my_tuple = (10, 20, 30)

# タプルの要素にアクセスする
print(my_tuple[0]) # 10が返る

 セットは集合を表現するデータ型で\{\}または組み込み関数\mathrm{set}を用いて用意する。セットは要素の重複を許さない。

##############
### セット ###
##############
# セットの定義
print({1, 2, 2, 2, 3, 4, 5})

print(set('abcccd'))

# セットへの要素の追加
my_set = set('abcccd')
my_set.add('e')
print(my_set)

# 空のセットを定義
my_set1 = {} # 辞書型になる
my_set2 = set()

print(type(my_set1))
print(type(my_set2))


1.1.4 変更の可否

 文字列には添字を用いて各文字にアクセスできる。他方でリストのように要素を変更することはできない。
 変更できないデータ型をイミュータブル(immutable)という。タプルはイミュータブルである。他方でリストは各要素を変更できるのでミュータブル(mutable)である。

# 文字列にアクセス
my_str = 'abcdef'
print(my_srt[2])

# 各文字を変更することは出来ない
my_str[2] = 'C' # エラーになる
1.1.5 組み込み関数

 組み込み関数は前準備無しに利用できる。

1.1.6 モジュールのインポート

 組み込み関数以外の関数やクラスを用いる場合、\mathrm{import}文を用いてモジュールを読み込む。

# random モジュールを読み込む
import random

# 乱数シードを設定する
random.seed(1)

print(random.random()) # 0から1の間の一様乱数を1つ返す
1.1.7 制御構文

 \mathrm{Python}の制御構文は繰り返しの\mathrm{for}文と\mathrm{while}文、条件分岐の\mathrm{if}文から構成される。

 繰り返しの\mathrm{for}文は例のように書く*1
 条件分岐の\mathrm{if}文も\mathrm{for}文と同様の書き方をする。条件を満たさない場合のために[tex;mathrm{else}]文を追記することもできる。
 繰り返しの\mathrm{while}文は条件を満たす限りループを続ける。ある条件を満たす場合に以後の処理をスキップし次のループに行くには\mathrm{continue}文を、条件を満たす場合にループを強制終了させるには\mathrm{break}を用いる。

import random

for i in range(3):
    print(i)

print('**************************************')
# 文字列やリスト型をinの中におけば各要素を取ってくる
for c in 'abc':
    print(c)

print('**************************************')

# 添字が欲しい場合はenumerateを用いると便利である
for i,c in enumerate('abc'):
    print(i,c)

print('**************************************')

# 条件分岐は if文を用いる
num = random.random()

print(num)
if num < 0.5:
    print('Small')
else:
    print('Large')

print('**************************************')
if num < 0.1:
    print('small')
elif num < 0.9:
    print('middle')
else:
    print('large')

print('**************************************')
# while文は指定した条件が成立する間ループをする
cnt = 0
while True: # 条件:今回はTrueとしたので永遠にループし続ける
    cnt += 1
    if cnt % 2 == 0: continue # 条件を満たすときに処理をスキップさせて次のループに移すのにcontinueを用いる
    if cnt >= 10: break # 条件を満たすときにループを強制終了させる場合はbreakを用いる
    print(cnt)

print('**************************************')
1.1.8 関数の作り方

 自作の関数を定義するにはキーワード\mathrm{def}を用いる。制御構文のように\mathrm{def}の行はコロンで終わらせ、次の行からが関数の内部であることを明確化すべくインデントする。
 関数の名前もスネークケースに則り命名する。\mathrm{return}を用いると戻り値を与えるようになる。関数の引数にはデフォルト値を与えることができる。
 関数を定義した場合、その直後に二重引用符を3つ重ねて\mathrm{docstring}と呼ばれる文字列にコメントを書く。これで第三者がその関数の意味を理解できるようにする。

# 何もしない関数
def func():
     pass # Pythonはコロンでインデントした後に何も記載しないことを許容しないため、それを表すためにpassを用いる

# 引数にデフォルト値を与えることができる
def func_cal(a, b, prefix ='<-- ', postfix = ' -->'):
    """ この関数はaをbで割った結果を返す(小数)。
    返り値はprefix, postfixで囲われた文字列。
    """
    return prefix + str(a / b) + postfix

# 実際に関数値を与える
print(func_cal(3,2))
print(func_cal(postfix = ']', prefix = '[', b = 2, a =6))
func_cal.__doc__ # docstringを返す
help(func_cal) # docstringを返す
1.1.9 変数とスコープ

 変数は何らかの名前空間に属している。関数の内側からのスコープはグローバル名前空間に達するため、関数の中からこのオブジェクトにアクセスできる。
 ローカル名前空間は関数の中に入るとグローバル名前空間と別に用意される。ローカル名前空間の中で新たに定義された変数はローカル名前空間に属しその外には影響を与えない。

1.1.10 クラスの作成

 \mathrm{Python}オブジェクト指向言語である。
 オブジェクトの設計図がクラスである。どのようなオブジェクトを生成するかをクラスに記述する。実際に使うときにはインスタンス(実体)を作る。
 新しいクラスはキーワード\mathrm{class}を用いて定義する。クラスの名前を書いた後にコロンを書き、インデントした後に具体的なコードを記載する。
 特殊メソッドの1つである\mathrm{__init__}を追加すると、クラスのインスタンスがつくられるときの動作を記述できる。
 以下はサイコロを模したクラスを生成する。

import random

########################
### クラスを定義する ###
########################

# 実体のないクラスを定義
class TestClass:
    pass

my_class = TestClass() # インスタンスを生成

class Dice:
    
    def __init__(self, num):
        self.face_num = num
    def shot(self):
        return random.randint(1, self.face_num)

# クラスDiceのインスタンスを生成する
dice = Dice(6)
dice.shot()

 クラスのメソッドは1つ目の引数として\mathrm{self}を取る。インスタンスメソッドに対して暮らすメソッドを作ることもできる。
クラスメソッドを定義する場合は、メソッドを\mathrm{@classmethod}で修飾し、1つ目の引数を\mathrm{cls}とする。

1.1.11 namedtuple

 \mathrm{collections}モジュールの\mathrm{namedtuple}を用いるとタプルの各要素に名前を付けることができ、コードが分かりやすくなる。

from collections import namedtuple

Person = namedtuple('Person', ['ID', 'name'])
p = Person(101, 'Taro')
print(p.name)
print(p)


1.1.12 エラー処理

 エラーが発生する可能性がある箇所は\mathrm{try}\mathrm{except}で囲むことで発生する可能性のあるエラーを処理できる。

def zero_div(a, b):
    try:
        c = a / b
    except:
        c = 'error!'
    return c

print(zero_div(4,2))
print(zero_div(4,0))

 \mathrm{Python}のエラーには種類がある。 値が不正な場合には\mathrm{ValueError}をキーワード\mathrm{raise}を用いて呼べばよい。

raise ValueError('値が不正です. ')

*1:半角空欄4つ分インデントを下げている。

プライバシーポリシー お問い合わせ