ホーム»プログラミング» 【プログラミング】[独学][Python-第3回]コレクションで複数データを扱う方法
a

【プログラミング】[独学][Python-第3回]コレクションで複数データを扱う方法

プログラミング

今回もノンプログラマーがPythonでさくっとプログラミングをしていきます。
前回は文字出力と変数の扱いかたをメインに紹介してきましたが、今回は多くの変数を便利に扱うことのできるコレクションについて説明していきます。

エクセルを扱うことが得意なVBAでは、これらのことを配列と呼んでたりしますが、Pythonではコレクションと呼ばれています。
コレクションはシステム開発などの業務などには関わっておらず、事務作業を単純自動化するなどのプログラムであれば、必ず使用しないとならないものでもないですが、コレクションを覚えることでプログラム全体の書き方スキルが向上することは間違いないです。

komori
komori

本記事は下記の様な方にオススメです!

  • 前回の記事を読んで変数については何となく理解できている方
  • 沢山のデータを扱うプログラムを作っていきたい方
  • Python少し書けるけど、書き方をもっと効率的にしたい方

今回も引き続きスッキリわかるPython入門を参考に進めていきます。

データの集まり(コレクション)を覚える前に

今回の本題に入る前に下記のコードをみてみましょう。

入力コード

gaiken = 65
yasashisa = 70
okanemochi = 40

#合計点を変数totalに代入する
total = gaiken + yasashisa + okanemochi
#平均点を変数avgに代入する
avg = total // 3

print(‘合計点:{}点’.format(total))
print(‘平均点:{}点’.format(avg))

実行結果

合計点:175点
平均点:58点

例えば、ここに変数kaji(家事スキル)の要素を追加したい場合、コードのアップデートが煩雑となる。
・上段の変数ブロックに変数の「kaji」を追加。
・合計点変数totalに変数の「kaji」を追加。
・要素を一つ追加したので平均を求める際の割る数を3から4に更新。

プログラムは初期時点で完璧であることに越したことはないですが、新しい機能やユーザのニーズによって柔軟に様々なアップデートをすることが前提となりますので、全体の可読性を向上させるように特定処理の部品化や、更新時の容易性を考慮して簡潔なコードを書く事も重要だと言えます。
これらを踏まえた上で次のコレクションを参考にして貰えば、覚えておくことが有効だと考えられるでしょう。

データの集まり(コレクション)で処理を実行する

コレクションの”リスト”を使う

リストの定義方法は下記のとおりです。
変数 = [値1,値2,値3…]

入力コード

status = [65, 70 , 40 , 80]
print(status)

実行結果

[65, 70, 40, 80]

リストの定義と値の代入。リストの場合は[]を用いて要素(値)ごとにカンマで区切ります。上記のコードでリストに登録したすべての値を出力しています。

リストを用いて要素の合計・平均を出してみる

入力コード

status = [65, 70 , 40 , 80]

total = status[0] + status[1] + status[2] + status[3]
print(f’リスト内の要素をひとつずつ足しても合計得点は{total}点です。’)

total = sum(status)
print(f’リスト内の要素をsum関数で足しても合計得点は{total}点です。’)


avg = sum(status)/len(status)
print(f’平均点は{avg}点です。’)

実行結果

リスト内の要素をひとつずつ足しても合計得点は255点です。
リスト内の要素をsum関数で足しても合計得点は255点です。
平均点は63.75点です。

リストstatusの合計値をsum関数で合計し、要素数を取得するlen関数で割って平均点を変数avgに代入した上で出力しています。

リスト内の要素を指定する

入力コード

status = [65, 70 , 40 , 80]
print(status[1])

実行結果

70

リスト内の要素を参照する場合は、変数名に添え字を[]付けて指定しています。
リスト内の要素は0番目からとなるので、[1]を指定すると70が返ってきます。

リストの要素を追加・変更・削除する

入力コード

jippongatana = [‘ちょう’,’かまたり’,’ほうじ’]
print(jippongatana)

#append関数を使ってリスト内の要素を追加する。(例:へんや、うすい、さいづち、ルフィを追加する)
jippongatana.append(‘へんや’),jippongatana.append(‘うすい’),jippongatana.append(‘ルフィ’),print(jippongatana)

#remove関数を使ってリスト内の要素を削除する。(例:ルフィを削除する)
jippongatana.remove(‘ルフィ’)
print(jippongatana)

#リスト内の要素を変更する。(例:へんやをあんじに変更する)
jippongatana[3]= ‘あんじ’
print(jippongatana)

print(f’リスト内の要素指定を負の数ですることもできる。添え字が-1の場合は「{jippongatana[-1]}」で-2の場合は「{jippongatana[-2]}」となる’)

実行結果

['ちょう', 'かまたり', 'ほうじ']
['ちょう', 'かまたり', 'ほうじ', 'へんや', 'うすい', 'ルフィ']
['ちょう', 'かまたり', 'ほうじ', 'へんや', 'うすい']
['ちょう', 'かまたり', 'ほうじ', 'あんじ', 'うすい']
リスト内の要素指定を負の数ですることもできる。添え字が-1の場合は「うすい」で-2の場合は「あんじ」となる

入力コード

jippongatana = [‘ちょう’,’かまたり’,’ほうじ’,’へんや’,’うすい’,’さいづち’,’ふじ’,’あんじ’,’そうじろう’,’いわんぼう’]
print(jippongatana[8])#8の要素を出力する

#スライスによるリスト内の要素範囲指定の記述方法(添え字の[]に:を記入して範囲を指定)
print(jippongatana[1:5])#1以上5未満までの要素を出力する(要するに1~4です。)
print(jippongatana[7:])#7以上の要素を出力する(要するに7を含めたあとの全部です。)
print(jippongatana[:4])#4未満までの要素を出力する(要するに3までの全部です。)

そうじろう
['かまたり', 'ほうじ', 'へんや', 'うすい']
['あんじ', 'そうじろう', 'いわんぼう']
['ちょう', 'かまたり', 'ほうじ', 'へんや']

コレクションの”ディクショナリ”を使う

ディクショナリの定義方法は下記のとおりです。
変数 = {キー1:値1,キー2:値2,キー3:値3…}
※キーと値をペアにし、カンマで区切って{}で括って記述します。

入力コード

jippongatana = {‘へんや’:30 , ‘かまたり’:45 , ‘あんじ’:65}
print(jippongatana)

実行結果

{'へんや': 30, 'かまたり': 45, 'あんじ': 65}

ディクショナリを用いて要素の合計・平均を出してみる

入力コード

jippongatana = {‘へんや’:30 , ‘かまたり’:45 , ‘あんじ’:65, ‘うすい’:75, ‘そうじろう’:80}
ninnzuu = len(jippongatana)#要素数の値を変数ninnzuuに代入する

total = sum(jippongatana.values())#要素の値の合計を変数totalに代入する
avg = sum(jippongatana.values())//len(jippongatana)#要素の値の平均を変数avgに代入する

print(‘現在のjippongatanaは{}人で戦闘力の合計は{}で、平均戦闘力は{}です。’.format(ninnzuu,total,avg))

実行結果

現在のjippongatanaは5人で戦闘力の合計は295で、平均戦闘力は59です。

ディクショナリ内の要素を参照する

入力コード

jippongatana = {‘へんや’:30 , ‘かまたり’:45 , ‘あんじ’:65}
print(jippongatana[‘かまたり’])#ディクショナリの要素を参照する際はキーを添え字にする。

実行結果

45

ディクショナリの要素を追加・変更・削除する

入力コード

jippongatana = {‘へんや’:30 , ‘かまたり’:45 , ‘あんじ’:65}

#ディクショナリの要素の追加と変更は同じ書き方
jippongatana[‘うすい’] = 75#キー’うすい’で値75を追加
jippongatana[‘かまたり’] = 40#’かまたり’の値を45→40に変更
print(jippongatana)


#ディクショナリの要素の削除
del jippongatana[‘へんや’]#’へんや’を削除する。
print(jippongatana)

実行結果

{'へんや': 30, 'かまたり': 40, 'あんじ': 65, 'うすい': 75}
{'かまたり': 40, 'あんじ': 65, 'うすい': 75}

コレクションの”タプル”を使う

続いてのコレクションは”タプル”となります。次のセットと同様にリストやディクショナリと比較して使用頻度は少ないですが、幅広い知識をもっていることで特性を利用することもプログラムを書くテクニックとなりますのでポイントだけでもおさえておきましょう。

タプルの定義方法は下記のとおりです。
変数=(値1,値2,値3,…)
※リストと異なる点は括弧が[]ではなく、()を使って記述するところです。

入力コード

jippongatana = (‘ちょう’,’かまたり’,’ほうじ’,’へんや’,’うすい’)
donut_price = (100,120,150,180,200)

print(jippongatana)#タプルの要素(jippongatana)を全て出力する
print(donut_price)#タプルの要素(donut_price)を全て出力する
print(type(jippongatana))#jippongatanaのデータ型を出力する
print(type(donut_price))#donut_priceのデータ型を出力する

実行結果

('ちょう', 'かまたり', 'ほうじ', 'へんや', 'うすい')
(100, 120, 150, 180, 200)
<class 'tuple'>
<class 'tuple'>

タプルはリストとよく似ているコレクションですが、大きく異なるポイントとしては、要素の追加・変更・削除ができないところとなります。イメージとしては中身が書き換えられないリストということで覚えておくと良いでしょう。

タプルを用いて要素の合計・平均を出してみる

リストやディクショナリと同様にSUM関数やLEN関数を用いて、タプルの要素内の合計や平均を出すことは可能です。

入力コード

donut_price = (100,120,150,180,200)
total = sum(donut_price)
avg = sum(donut_price)//len(donut_price)

print(‘ドーナツの合計額は{}円で、平均価格は{}円です。’.format(total,avg))

実行結果

ドーナツの合計額は750円で、平均価格は150円です。

タプル内の要素を指定する

要素を指定する場合も他のコレクション同様に[]で添え字を付けて書きます。
但し、コレクションの要素は0番から始まることには注意してください。

下の画像では、タプルのjippongatanaの5番目の”うすい”を添え字[4]を指定することで表示しています。同様にタプルのdonut_price[2]を指定して、3番目の150の要素を指定しています。

入力コード

jippongatana = (‘ちょう’,’かまたり’,’ほうじ’,’へんや’,’うすい’)
donut_price = (100,120,150,180,200)

print(‘5番目の要素は{}です。’.format(jippongatana[4]))#タプル要素内の5番目の要素を出力する。※添え字は0番から指定します。
print(‘3番目の要素は{}です。’.format(donut_price[2]))#タプル要素内の3番目の要素を出力する。※添え字は0番から指定します。

実行結果

5番目の要素はうすいです。
3番目の要素は150です。

また、リストでも使った下記のようなスライスも可能です。

入力コード

jippongatana = (‘ちょう’,’かまたり’,’ほうじ’,’へんや’,’うすい’)
print(‘2から4番目の要素は{}です。’.format(jippongatana[1:4]))

実行結果

2から4番目の要素は('かまたり', 'ほうじ', 'へんや')です。

タプル要素内2番目から4番目の要素を出力する。※添え字は0番から指定しますので1番目から5番目未満となります。

入力コード

donut_price = (100,120,150,180,200)
print(‘1番目から3番目までの要素は{}です。’.format(donut_price[:3]))

実行結果

1番目から3番目までの要素は(100, 120, 150)です。

タプル要素内の3番目までの要素を出力する。※添え字は0番から指定しますので4番目未満となります。

タプルの要素数が一つだった場合の生成

コレクションは複数のデータを扱うことが一般的ですが、タプル型で要素が一つだった場合の注意点について説明します。

入力コード

jippongatana = (‘そうじろう’)#要素数が一つの場合のタプル定義
print(type(jippongatana))#type関数によるデータ型の出力

実行結果

<class 'str'>

str(文字列)型と認識されてしまってます。

入力コード

jippongatana = (‘そうじろう’,)#要素数が一つの場合のタプル定義 ※カンマをつけること
print(type(jippongatana))#type関数によるデータ型の出力 

実行結果

<class 'tuple'>

タプルだと認識されました。

コレクションの”セット”を使う

セットもコレクションの一つとなりますが、リストと似ています。リストと異なる点を抑えておきましょう。

・重複した値を格納することができない
・添え字やキーという概念がなく、特定の要素に代入・参照する方法が存在しない
・添え字がないため、要素は順序をもたない。
・appned関数の代わりにadd関数で要素を追加する

komori<br>
komori

👉Tips
コレクションのセットは、決まった種類を管理することに向いています。信号機の色の赤・青・黄については特に序列をもたない要素なので、こういったものを代入するにはセットは使えるでしょう。

セットの定義方法は下記のとおりです。
変数={値1,値2,値3,…}
※リストと異なる点は括弧が[]ではなく、{}を使って記述するところです。

入力コード

shingou = {‘赤’,’黄’,’青’}
finger = {‘親’,’人指し’,’中指’,’薬指’,’小指’,’人指し’}#人指しを重複して登録
donut_price = {100,120,150,180,200}

print(shingou)
print(type(shingou))
print(finger)#人指しは一つのみ存在し、重複していない
print(type(finger))
print(donut_price)
print(type(donut_price))

実行結果

{'赤', '青', '黄'}
<class 'set'>
{'中指', '人指し', '薬指', '小指', '親'}
<class 'set'>
{100, 200, 180, 150, 120}
<class 'set'>

セットを用いて要素の合計・平均を出してみる

入力コード

donut_price = {100,120,150,180,200}

total = sum(donut_price)
avg = sum(donut_price)//len(donut_price)
print(‘ドーナツの合計額は{}円で、平均価格は{}円です。’.format(total,avg))

実行結果

ドーナツの合計額は750円で、平均価格は150円です。

セットの要素を追加・削除する

入力コード

shingou = {‘赤’,’黄’,’青’}
donut_price = {100,120,150,180,200}

shingou.add(‘紫’)#紫の要素を追加する。
print(shingou)

shingou.remove(‘黄’)
#黄の要素を削除する。
print(shingou)
#discard(‘黄’)の記述も可。
remove引数に指定した要素が存在しない場合エラー

donut_price.add(85)#85の要素を追加する。
print(donut_price)

donut_price.discard(180)#180の要素を削除する。
print(donut_price)

#remove(180)の記述も可。discardは引数に指定した要素が存在しない場合も正常終了

実行結果

{'赤', '紫', '青', '黄'}
{'赤', '紫', '青'}
{100, 200, 180, 85, 150, 120}
{100, 200, 85, 150, 120}


データの集まり(コレクション)で処理を実行する応用編

コレクションの相互変換

これまで4つのコレクションを紹介しましたが、それぞれの相互変換が可能です。
変換する際の記述方法は下記のとおりです。

関数説明
list関数渡されたものをリストに変換する。※1
tuple関数渡されたものをタプルに変換する。※1
set関数渡されたものをセットに変換する。※2
※1 ディクショナリやセットからの変換された場合は順序が保証されない
※2 リストやタプルからの変換された場合は重複が排除される
※3 list()のように書くと、空のコレクションを作成することができる

入力コード

jippongatana = [‘ちょう’,’かまたり’,’ほうじ’,’へんや’,’うすい’,’かまたり’]
print(jippongatana)
print(type(jippongatana))

Pokemon = (‘ピカチュウ’,’フシギダネ’,’ゼニガメ’,’ヒトカゲ’,’フシギダネ’)
print(Pokemon)
print(type(Pokemon))

shingou = {‘赤’,’黄’,’青’}
print(shingou)
print(type(shingou))

print(list(Pokemon))#タプル(pokemon)をリストに変換して表示する。
print(list(shingou))#セット(shigou)をリストに変換して表示する。 print(tuple(jippongatana))#リスト(jippongatana)をタプルに変換して表示する。 print(tuple(shingou))#セット(shingou)をタプルに変換して表示する。 print(set(jippongatana))#リスト(jippongatana)をセットに変換して表示する。 print(set(Pokemon))#タプル(Pokemon)をセットに変換して表示する。

実行結果

['ちょう', 'かまたり', 'ほうじ', 'へんや', 'うすい', 'かまたり']
<class 'list'>
('ピカチュウ', 'フシギダネ', 'ゼニガメ', 'ヒトカゲ', 'フシギダネ')
<class 'tuple'>
{'黄', '青', '赤'}
<class 'set'>
['ピカチュウ', 'フシギダネ', 'ゼニガメ', 'ヒトカゲ', 'フシギダネ']
['黄', '青', '赤']
('ちょう', 'かまたり', 'ほうじ', 'へんや', 'うすい', 'かまたり')
('黄', '青', '赤')
{'ちょう', 'ほうじ', 'うすい', 'へんや', 'かまたり'}
{'ピカチュウ', 'フシギダネ', 'ヒトカゲ', 'ゼニガメ'}

11・12行目でセットへ変更したことで’かまたり’と’フシギダネ’が重複排除となっています。

ディクショナリからリスト・タプル・セットへ変換するとキー部分だけが使われます。ディクショナリの値を使いたい時の書き方は下記のとおりです。

入力コード

jippongatana = {‘へんや’:30 , ‘かまたり’:45 , ‘あんじ’:65}
print(jippongatana)
#リストへの変換
print(list(jippongatana))
print(list(jippongatana.values()))
#タプルへの変換
print(tuple(jippongatana))
print(tuple(jippongatana.values()))
#セットへの変換
print(set(jippongatana))
print(set(jippongatana.values()))

※ディクショナリの値を扱いたい時はディクショナリ名.values()を関数に渡すように記述します。

実行結果

{'へんや': 30, 'かまたり': 45, 'あんじ': 65}
['へんや', 'かまたり', 'あんじ']
[30, 45, 65]
('へんや', 'かまたり', 'あんじ')
(30, 45, 65)
{'へんや', 'かまたり', 'あんじ'}
{65, 45, 30}

入力コード

ディクショナリへの変換は少し特殊なものとなりますので、上記3つのコレクションとは別で説明しますが、キーと値の2つのコレクションで構成して変換します。

l_jippongatana = [‘ちょう’,’かまたり’,’ほうじ’,’へんや’,’あんじ’,’うすい’,’そうじろう’]
l_sentouryoku = [35,45,15,30,75,65,80]

t_jippongatana = (‘ちょう’,’かまたり’,’ほうじ’,’へんや’,’あんじ’,’うすい’,’そうじろう’)
t_sentouryoku = (35,45,15,30,75,65,80)

s_jippongatana = {‘ちょう’,’かまたり’,’ほうじ’,’へんや’,’あんじ’,’うすい’,’そうじろう’} s_sentouryoku = {35,45,15,30,75,65,80}

print(dict(zip(l_jippongatana,l_sentouryoku)))#リストからディクショナリ print(dict(zip(t_jippongatana,t_sentouryoku)))#タプルからディクショナリ print(dict(zip(s_jippongatana,s_sentouryoku)))#セットからディクショナリ

実行結果

{'ちょう': 35, 'かまたり': 45, 'ほうじ': 15, 'へんや': 30, 'あんじ': 75, 'うすい': 65, 'そうじろう': 80}
{'ちょう': 35, 'かまたり': 45, 'ほうじ': 15, 'へんや': 30, 'あんじ': 75, 'うすい': 65, 'そうじろう': 80}
{'ちょう': 65, 'ほうじ': 35, 'あんじ': 75, 'うすい': 45, 'そうじろう': 15, 'へんや': 80, 'かまたり': 30}
{'ちょう': 35, 'かまたり': 45, 'ほうじ': 15, 'へんや': 30, 'あんじ': 75, 'うすい': 65, 'そうじろう': 80}
komori
komori

リスト×タプル、リスト×セット、タプル×リスト、タプル×セット、セット×リスト、セット×タプルなどの混在でもディクショナリへの変換可能です。

コレクションのネスト

コレクションの2重構造なども作成可能です。
例1.ディクショナリの中にディクショナリをネストしてみます。

入力コード

henya = {‘腕力’:15,’体力’:15,’素早さ’:60}
kamatari = {‘腕力’:45,’体力’:50,’素早さ’:40}
anji = {‘腕力’:90,’体力’:85,’素早さ’:20}

jippongatana = {
‘へんや’:henya,
‘かまたり’:kamatari,
‘あんじ’:anji
}

print(jippongatana)

実行結果

{'へんや': {'腕力': 15, '体力': 15, '素早さ': 60}, 'かまたり': {'腕力': 45, '体力': 50, '素早さ': 40}, 'あんじ': {'腕力': 90, '体力': 85, '素早さ': 20}}

例2.ディクショナリにセットをネストしてみます。

入力コード

jippongatana_hobbies = {
‘へんや’:{‘飛行’,’軽量化’},
‘かまたり’:{‘買物’,’物色’,’お茶’},
‘あんじ’:{‘鍛錬’,’瞑想’,’読経’}
}
print(jippongatana_hobbies)

実行結果

{'へんや': {'軽量化', '飛行'}, 'かまたり': {'お茶', '物色', '買物'}, 'あんじ': {'瞑想', '読経', '鍛錬'}}

例3.リストの中にリストをネスト(2次元リスト)してみます。

入力コード

kamatari = [45,50,40]
anji = [90,85,20]

jippongatana = [kamatari,anji]

print(jippongatana)
print(jippongatana[0])
print(jippongatana[1])
print(jippongatana[0][1])#jippongatanaリストの0番目(kamatari)の1番目は50 print(jippongatana[1][0])#jippongatanaリストの1番目(anji)の0番目は90

実行結果

[[45, 50, 40], [90, 85, 20]]
[45, 50, 40]
[90, 85, 20]
50
90

集合演算

集合演算とは2つのセットの共通点や違いを探す処理のことです。
こういった演算処理は、データ分析をおこなう上では非常に役立つものとなります。

入力コード

jippongatana_hobbies = {
    'かまたり':{'買物','物色','お茶'},
    'あんじ':{'鍛錬','瞑想','読経','お茶'}
}

common_hobbies = jippongatana_hobbies['かまたり'] & jippongatana_hobbies['あんじ']
print(common_hobbies)#2つのセット(かまたりとあんじの趣味)に共通する値を出力する

dragonquest ={1,2,3,4,5,6,7,8,9,10,11}
biohazard = {0,1,2,3,4,5,6,7}

print(dragonquest | biohazard)#和集合(双方に存在する全ての値を列挙)
print(dragonquest & biohazard)#積集合(双方に存在し、共通している値を列挙)
print(dragonquest - biohazard)#差集合(dragonquestに存在し、biohazardに存在しない値を列挙)
print(dragonquest ^ biohazard)#対称差(双方の差分の値を列挙)

実行結果

{'お茶'}#積集合
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}#和集合
{1, 2, 3, 4, 5, 6, 7}#積集合
{8, 9, 10, 11}#差集合
{0, 8, 9, 10, 11}#対称差

Pythonでコレクションを扱って数多くのデータを扱ってみようまとめ

今回はコレクションの使い方について紹介しました。
最後に今回のコレクションに関するまとめを表にしておきますので是非参考にしてください。

特徴リストディクショナリタプルセット
格納内容複数の値複数の「キーと値のペア」複数の値複数の値
定義方法[値1,値2…]{キー1:値1,キー2:値2}(値1,値2…){値1,値2…}
個別要素の参照変数名[添え字]変数名[キー]変数名[添え字]困難※
要素の追加変数名.append(値)変数名[キー]=値不可変数名.add(値)
要素の変更変数名[添え字]=値変数名[キー]=値不可困難※
要素の削除変数名.remove(値)del 変数名[キー]不可変数名.remove(値)
要素の順序関係ありなしありなし
重複値の格納キーは不可
値は可
不可
集合演算不可不可不可
len関数による要素数の取得
sum関数による合計値の取得不可
スライスの利用不可不可
+演算子による連結不可不可
※キーや添え字を用いた操作は不可能、繰り返し処理による操作は可能。


沢山のデータを扱う際にはこれらを用いてプログラムを書くことで、より効率的にコードを書いていくことが出来るようになると思います。
私が最初にこの本を読んでPythonの勉強し始めた時は、この辺りで一度つまづいたと記憶していますが、プログラミングを勉強していくことに限らず、初見での理解が十分でなくても読み進めていって、一度読み切ってから理解できないところを読み返すようにしています。

なぜなら、今時点で理解につまづいた部分で学習が止まってしまうことと、先に進めないことで同じ部分を繰り返し読むことになり、結果として面白味がなくなっていくので学習に向けてのモチベーション維持が減退していく傾向が出やすくなるからです。ですから、一度読んでも理解ができない部分は改めて読み返すつもりで、さくさく進めていく方が楽しみながら学習を進めることができますよ。

さて、今回はここまでとなります。さいごまでお付き合いありがとうございました。
次回は「条件分岐」の書き方について紹介します。

コメント

タイトルとURLをコピーしました