乙Py先生のプログラミング教室
初学者のためのプログラミング学習サイト

プログラミング

                 30.内包表記

内包表記はpython独特の書き方で
一定の処理を簡素に書くための手法となります。

内包表記の書き方

リスト:[counter for counter in iterator] 
辞書 :{key:value for key,value in iterator} 
セット:{counter for counter in iterator}

内包表記を使ってリストを作る

In [1]:
# 内包表記で変数にリスト型を格納する
lis1 = [i for i in range(10)]
print(lis1)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

内包表記を使わない場合は

In [2]:
lis2 = []
for i in range(10):
    lis2.append(i)
print(lis2)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

内包表記は複数行にわたる処理を1行にまとめる事ができる。

内包表記を使って辞書を作る

In [3]:
# 内包表記でキーをenumerate , 値をrangeの結果として辞書型を作成
num_dict = {k:v for k,v in enumerate(range(2,30,3))}
print(num_dict)
{0: 2, 1: 5, 2: 8, 3: 11, 4: 14, 5: 17, 6: 20, 7: 23, 8: 26, 9: 29}

keyとvalueに該当するものが有れば辞書型を作成可能。

内包表記はIF文を用いることもできます。

内包表記 + IF文

リスト:[value for counter in iterator if conditions]

辞書 :{key:value if conditions for key,value in iterator}

内包表記 + IF , else文

リスト:[value if conditions else value for counter in iterator]

辞書:{k1 if conditions else k2 : v1 if conditions else v2 for key:value in iterator}

In [4]:
# リスト内包表記 + IF文
num_list = [i for i in range(15) if i%2==0]
print(num_list)
[0, 2, 4, 6, 8, 10, 12, 14]
In [5]:
# リスト内包表記 + IF , else文
num_list = [i if i%2==0 else 0 for i in range(15) ]
print(num_list)
[0, 0, 2, 0, 4, 0, 6, 0, 8, 0, 10, 0, 12, 0, 14]
In [6]:
# 辞書内包表記 + IF文
num_dict = {k:v for k,v in enumerate(range(2,30,3)) if k%2==0}
print(num_dict)
{0: 2, 8: 26, 2: 8, 4: 14, 6: 20}
In [7]:
# 辞書内包表記 + IF , else文
num_dict = {k if k%2==0 else 0 : v if k%2==0 else 0  for k,v in enumerate(range(2,30,3)) }
print(num_dict)
{0: 0, 8: 26, 2: 8, 4: 14, 6: 20}

辞書型はenumerateを用いずにzip関数でリスト2つを用いても作る事ができる。

In [8]:
lis_a = [1,2,3,4,5]
lis_b = ['a','b','c','d','e']
d2 = {k:v for k,v in zip(lis_a,lis_b)}
print(d2)
{1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e'}

リスト内包表記から辞書を作成する事もできます。

In [9]:
# リスト内包表記から辞書化
num_dict = dict((str(i),i) if i%2==0 else (i,str(i)) for i in range(10))
print(num_dict)
{9: '9', 1: '1', 3: '3', '8': 8, 5: '5', '0': 0, '2': 2, '4': 4, '6': 6, 7: '7'}

for文は複数書くことができます。

In [10]:
# 2重の内包表記
print([i*j for i in range(1,5) for j in range(1,4) ])
[1, 2, 3, 2, 4, 6, 3, 6, 9, 4, 8, 12]

これを通常のfor文で書いて見ましょう。

In [11]:
a5 = []
for i in range(1,5):
    for j in range(1,4):
        a5.append(i * j)
print(a5)
[1, 2, 3, 2, 4, 6, 3, 6, 9, 4, 8, 12]

後に書いた方が内側のfor文に該当します。

このように複数行に渡るものも1行でスッキリ書くことができるのが
内包表記の良いところです。

まずは通常の処理を正しく書くことから始め、
それを簡略化できる部分があれば、内包表記に変えてゆく
といった風にすると、上手に覚えることができると思います。

                 29.ソート

ソートはデータを並べ替えを行います。

プログラムの中ではかなり多く用いられる処理です。

文字列型の並び替え

インデックスを用いて文字列を逆さまにすることができます。

In [1]:
a1 = 'abcdeアイウエオ123幹事!'
# [::-1]で逆さまにする
print(a1[::-1])
!事幹321オエウイアedcba

文字列内で使われている文字を並び替えるには
一旦リスト型に変換してから並び替えし、文字列に戻すことで
文字列の並び替えを実現できます。

sorted関数を使うと、文字列を分割して並び替えを行います。
第二引数のreverseにTrueを指定すれば降順
Falseを指定するか第二引数なしの場合は昇順となります。

In [2]:
a2 = 'abcdeアイウエオ123幹事!'
# sorted関数でリストに変換して昇順ソート
print(sorted(a2,reverse=False))

# sorted関数でリストに変換して降順ソート
print(sorted(a2,reverse=True))
['!', '1', '2', '3', 'a', 'b', 'c', 'd', 'e', 'ア', 'イ', 'ウ', 'エ', 'オ', '事', '幹']
['幹', '事', 'オ', 'エ', 'ウ', 'イ', 'ア', 'e', 'd', 'c', 'b', 'a', '3', '2', '1', '!']

join関数を用いるとリスト型のものを1つづつ連結して
文字列にすることができます。

In [3]:
a3 = 'abcdeアイウエオ123幹事!'

print(''.join(sorted(a3 , reverse=True)))
幹事オエウイアedcba321!

あまり文字列だけでの並び替えは
使う機会がないかもしれませんが、いざという時に役立つ手法です。

リスト型のソート

リスト型の関数であるsort関数を使う方法

昇順:
変数名.sort()

降順:
変数名.sort(reverse=True)

sorted関数を用いる方法

昇順:
sorted(変数名)

降順:
sorted(変数名,reverse=True)

※sorted関数は元のリストの並び順に影響しないが
sort関数はリストの並び替えを行い、リスト型の並び順が変わる。

In [4]:
lis1= [3,1,2,4,5,7,6]
print(lis1)

# 昇順ソート
print(sorted(lis1))

# sorted関数の後に再度呼び出しても順番は変わら無い
print(lis1)
[3, 1, 2, 4, 5, 7, 6]
[1, 2, 3, 4, 5, 6, 7]
[3, 1, 2, 4, 5, 7, 6]
In [5]:
lis2= [3,1,2,4,5,7,6]
print(lis2)

# 降順にソート
lis2.sort(reverse=True)
# sort関数の後に呼び出すと順番は変わる
print(lis2)
[3, 1, 2, 4, 5, 7, 6]
[7, 6, 5, 4, 3, 2, 1]

順番がプログラムに大きな影響を与える場合は注意が必要

元の形を保持したままにするのか、並び替えてから使うのか
処理のさせ方を考えて使い分けをします。

辞書型のソート

辞書型の並び替えは
キーの昇順と降順
値での昇順と降順
この4通りが存在します。

キー昇順:sorted(dct.items())

値の昇順:sorted(dct.items(), key=lambda x:x[1])

キー降順:sorted(dct.items(), reverse=True)

値の降順:sorted(dct.items(), key=lambda x:x[1],reverse=True)

In [6]:
# キー昇順
dct = { 2:3, 3:4, 1:2, 0:8, 4:2 }
for k, v in sorted(dct.items()):
    print(k,':',v)
0 : 8
1 : 2
2 : 3
3 : 4
4 : 2
In [7]:
# キー降順
dct = { 2:3, 3:4, 1:2, 0:8, 4:2 }
for k, v in sorted(dct.items(), reverse=True):
    print(k,':',v)
4 : 2
3 : 4
2 : 3
1 : 2
0 : 8
In [8]:
# Value昇順
dct = { 2:'3', 3:'4', 1:'2', 0:'8', 4:'2' }
for k, v in sorted(dct.items(), key=lambda x:x[1]):
    print(k,':',v)
1 : 2
4 : 2
2 : 3
3 : 4
0 : 8
In [9]:
# Value降順
dct = { 2:'3', 3:'4', 1:'2', 0:'8', 4:'2' }
for k, v in sorted(dct.items(), key=lambda x:x[1],reverse=True):
    print(k,':',v)
0 : 8
3 : 4
2 : 3
1 : 2
4 : 2

lambdaというのはラムダと読み、
pythonでは無名の関数を表す予約語になります。

ラムダについては後の講義で詳しくやって行きたいと思いますので、
ここでは割愛しますが、辞書の値で並び替えするには、
こういった書き方をしなくてはいけません。

辞書型そのものは並び順が大きな意味を持たないデータ型であるので
それを使うときにだけ並び替えを行うのが一般的です。

例えば、最終的に上位1番だけを出力する
といった時には降順で並び替えて出力する、ということを行います。

In [10]:
dct = { 2:'3', 3:'4', 1:'2', 0:'8', 4:'2' }

# まず辞書を値の降順ソートしてからenumrate関数に組み込む
for i , d  in enumerate(sorted(dct.items(), key=lambda x:x[1],reverse=True)):
    if i>=1:
        # 2回目で処理を抜ける
        break
    print(i,d[0],d[1])
0 0 8

繰り返しの処理を行う際にまず、辞書を値の降順でソートしておきます。
enumerate関数から返されるカウント数をみて繰り返しの処理を抜けます。

そうすることでデータが大量にある際に、上位何番まで出力するといった
ことも実現できるようになります。

注意点としてはenumerate関数と辞書型のitemsを使うと、返ってくるデータ型は
数値型とタプル型なので気をつけてください。

pythonではsorted関数を用いることで、
様々な形のデータの並び替えを行うことができます。

並びが重要なものを取り扱うプログラムを作るのに役立つと思います。

                 28.zip関数

zip関数は
リスト型を2つ用いて繰り返しの中などで同時に使うことを
できるようにする関数です。

まずはリスト型の変数を二つ用意します。

これをfor文で使っていきます。

In [1]:
a = [1,2,3,4,5]

b = [6,7,8,9,0]

for i , j in zip(a,b):
    print(i,j)
1 6
2 7
3 8
4 9
5 0

変数i , j にはそれぞれ元のリスト型の変数の値が格納されることになります。

もしzip関数を用いないで、2つのリストを使おうとすると
こんな感じになってしまいます。

In [2]:
count=0
for i in a:
    print(i , b[count])
    count+=1
1 6
2 7
3 8
4 9
5 0

当然バグの元にもなり得るので
処理としてまとめられるのであれば
zip関数を使ってしまった方が楽でコードもスッキリします。

zip関数で使えるリスト型のデータについては
同じ要素数である必要があります。

                 27.enumerate関数

さてfor文で繰り返しの書き方をやりましたが、覚えていますか
for文の書き方のおさらいです。

for文ではrange関数などを使って繰り返しの回数を指定していました。

In [1]:
for i in range(5):
    print(i)
0
1
2
3
4

このようにするとrange関数には0から4までの数値が生成され、
for文としては5回処理が繰り返されます。

enumerate関数はこのfor文の処理に
回数を数える変数を付け足すことができます。

In [2]:
# 5から9までの整数を生成して繰り返し処理する。
for i , j in enumerate(range(5,10)):
    print(i , j)
0 5
1 6
2 7
3 8
4 9

どんな時に使うかというと
処理が行われた回数を数えて、
回数で処理を抜けるような場合に
用いる事ができる。

In [3]:
count = 0
for i in range(5):
    print(i)
    if i>=3:
        break
    count+=1
0
1
2
3
In [4]:
for i , j in enumerate(range(5)):
    print(i,j)
    if i>=3:
        break
0 0
1 1
2 2
3 3

無駄な変数への代入などを省いて、コードを簡略化でき
バグを少なくすることができるのがこの関数の利点です。

for文などで繰り返しの回数をカウントしたり、値として
用いたりするのに役立つ関数になっているので
繰り返しの処理を書く際には便利な関数です。

                 26.組み込み関数について

pythonでは標準の機能として
組み込み関数というのが備わっています。

この講座のはじめから使っている
print()関数なども組み込み関数です。

プログラムには欠かすことのできない機能であるため
組み込み関数の使い方を学んでいきましょう。

関数の使い方

関数名(引数,・・・)

関数名の後のカッコに指定するものを引数と言い
引数は関数によっては複数存在することもあります。

その場合は「カンマ」で区切ることで、
何番めの引数に該当するかを指定できます。

関数を実行した結果は、何かしらの値が返ってくることがあります。
この返却される値のことを「戻り値」と言っています。

様々な組み込み関数

abs関数

数の絶対値を返す。

In [1]:
print(abs(2.5))

print(abs(-12.2))
2.5
12.2

float関数

文字や整数値から浮動小数点の値に変える。
文字は数字でなくてはダメ。文字も小数点と数字だけ。

In [2]:
print(float(13))

print(float('15.5'))
13.0
15.5

hex関数

数値を16進法の文字列に直す

In [3]:
print(hex(255))
print(hex(16))
0xff
0x10

※0xが付くのは16進法の表記法
0から始まって16になると桁が繰り上がる。

16進数の先頭の0x付きや無しに変換したい場合は
format関数を用いて実現できます。

In [4]:
print(format(255 , 'x'))
print(format(255 , 'X'))
print(format(255 , '#x'))
ff
FF
0xff

input関数

入力欄が出てきて
プログラムに対して入力を行うことができる。

In [5]:
s = input('--> ') 
print(s)
--> 入力したよ
入力したよ

int関数

文字列や小数点を整数値に変える。
文字列の場合は数字のみで整数のみ、小数点はエラー

In [6]:
print(int(12.3))
print(int('13'))
print(int(0.9))
12
13
0

小数点以下は切り捨て

len関数

引数に指定したオブジェクトの長さを返す。

In [7]:
a = 'こんにちは、マット・デイモンです。'
# 文字数を返す
print(len(a))
17
In [8]:
b = [1,2,3,4,5]
# リストの要素数を返す
print(len(b))
5

list関数

引数に指定したオブジェクトをリスト型に変換

In [9]:
# 辞書型を定義
d1 = {1:2,3:4,5:6}
print(d1)

# キーをリストに変換
print(list(d1.keys()))

# 値をリストに変換
print(list(d1.values()))

# キーと値のタプル型の要素を持つリストに変換
print(list(d1.items()))
{1: 2, 3: 4, 5: 6}
[1, 3, 5]
[2, 4, 6]
[(1, 2), (3, 4), (5, 6)]

dict関数

キーと値の2つの組み合わせになっているものであれば 辞書型に変換

In [10]:
# タプル型の要素を持つリストを辞書に変換
d2 = dict([('k1', 1), ('k2', 2), ('k3', 4)])
print(d2)
{'k1': 1, 'k2': 2, 'k3': 4}

max,min関数

maxは複数指定したオブジェクトの中で、一番大きなものを返す。
min関数はその逆で、最小の値を返す。

In [11]:
sample_list = [1,2,3,4,5,6]
# 最大値を返す
print(max(sample_list))
# 最小値を返す
print(min(sample_list))
6
1
In [12]:
sample_st= 'apple'
# 最大値を返す
print(max(sample_st))
# 最小値を返す
print(min(sample_st))
p
a

oct関数

数値を8進法の値に変換

In [13]:
print(oct(8))
print(oct(2))
0o10
0o2

open関数

ファイルを開いてファイルオブジェクトを作る関数。
こちらは紹介だけで、後の講義で詳細解説。

range関数

引数に指定した回数分のオブジェクトを生成する。

range(回数)
range(開始 , 終了)
range(開始 , 終了 , 間隔)

In [14]:
# 4つの整数を生成
print(list(range(4)))
[0, 1, 2, 3]

round関数

小数点を丸めて、一番近い整数を返す。

In [15]:
print(round(3.499)) 
print(round(3.5))
3
4

第二引数に桁を追加すると、その小数点の桁数で丸めを行う。

In [16]:
print(round(3.5187,3))
print(round(3.5187,1))
3.519
3.5

sorted関数

引数に指定したオブジェクトの要素の並び替えを行う。
※sorted関数の詳しい使い方に関しては後のソートの講義で

str関数

引数に指定したものを文字列に変換

In [17]:
# 整数値を文字列に変換
print(str(12))
12

sum関数

リスト型の要素の合計値を返す。
※要素が数値で無いとダメ

In [18]:
li =[1,2,3,4]
print(sum(li))
10

zip関数
enumerate関数

詳細は後の講義で。

関数は複数を組み合わせて使うことも可能

In [19]:
# 文字を小数点にしてから整数値に変換して絶対値にする。
print(abs(int(float('-3.14'))))
3

カッコの最も内側に有るものの処理が先に行われる。

関数ではこのように複数を組み合わせて使って行くのが一般的になりますが
処理が複雑になり、追って行くのも大変になります。

まずは一番初めに処理が行われる部分を探して、その結果が正しいのか
ということを一つ一つ追って行くのが良いと思います。

このページのトップヘ