ここでは以前に説明しなかった組み込み型(良く使われるデータ型のこと)の中でlist(リスト型),str(文字列型),について詳しく説明します.ここで扱われる「リスト型」,「文字列型」は複数の要素を持ち,インデックス(後で説明します)でアクセスできる「シーケンス型」と呼ばれる種類になります.
数学で使う「$n$次元ベクトル($x ={x_1, x_2, x_n}$)」,「1時間ごとに記録した気温のような取得したデータ」のデータ解析,「テキストファイルに書かれている文字列を改行で分割して行ごとにまとめたデータ」のテキスト処理など複数のデータを一覧にして管理し取り扱いたい場合があります.このような場合にPythonではリスト型(list)を使います.[]で囲ってintやstrと同じように変数に代入して定義します.(pythonの「リスト」は他のプログラミング言語の「配列」と似ています.同じではありません.「リスト」と「配列」の両方を持つ言語もあります(例えば,Java).)
a = [10, 20, 30, 40] # 4つの要素をもつリスト型を定義する
print(a) # a(リスト型)を出力する
print(type(a)) # aの型を調べ出力する
リストは文字列を要素として持つこともできます.
moji = ["mathematics", "physics", "information", "engineering"] # 要素として文字列をもつ
print(moji)
リストの要素としては数値と文字列を同時に持つことも可能であり、またリストの要素としてリストを持つことも可能です.
a1 = [1, 2, 3, "a", "b", "c"] # リストは数値型と文字列型の要素を同時に持つことができる。
print(a1)
b = [1, 2, 3, [4, 5, 6]] # リストの要素としてリストを持つこともできる
print(b)
リストは各要素には最初から順番に整数のインデックス(添え字)が振られてます.このインデックスはリストの要素をとりあつかう際にとても便利です.リストのインデックスは0番から始まることに注意してください.
a = [10, 20, 30, 40] #リストを準備
print(a[0]) # インデックスを用いてリストの要素を表示
print(a[-1]) # 負のインデックスも用いる事ができる
変数にリストを代入することなく直接インデックスを用いる事もできます.
print([10, 20, 30, 40][1]) # 直接リストのインデックスを指定して表示
リストの要素とインデックスの対応関係は下記の図の通りです.

リストの要素にリストを用いる事で,2次元リスト(行列)を作成することもできます.以下のリストmat01は行列$\begin{bmatrix}
1 & -1 & 1\\
2 & -1 & 2 \\
3 & -2 & 4
\end{bmatrix}$
を表しています.
mat01 = [[1, -1, 1], [2, -1, 2], [3, -2, 4]] # リストの要素をリストとして持つことで行列を表現
mat01
2次元リストの要素は次のようにインデックスを用いて取り出せます.(この例では3行1列の要素$a_{31}=3$を取り出してます)
mat01[2][0] # 2次元インデックスで指定しリストの値を取り出す
インデックスを用いて,リストeng =["環境システム学科", "数理工学科", "建築デザイン学科"]から「数理工学科」を取り出し出力しなさい.
任意の整数のベクトルの要素を持つ3次元ベクトル$a=[a_x, a_y, a_z]$,$b=[b_x, b_y, b_z]$の内積をリストを用いて求めなさい.
リストの中から複数の要素を取り出すスライスという機能があります.例えば a = [10, 20, 30, 40]というリストの内インデックス1~2まで(つまり,20と30の要素)取り出す場合には次のように書きます.
a[1:3] # スライス機能を用いてリストから複数の要素を取り出す
:の後ろに指定する整数は取り出したい要素のインデックスに1加えた整数となっていることに注意してください.
スライスには下記のように色々な指定方法があります.
a[:2] # インデックス0~1までの要素を取り出す
a[2:] # インデックス2~最後までの要素を取り出す
リストa = [10, 20, 30, 40]に対し,次のスライス操作を行ったらどのような要素を取り出せるか?確認してみてください。 a[-2 : 3]
リストはよくforループのような繰り返し処理と一緒に使われます.
test1 =[0, 1, 2, 3, 4] # リストを準備
for i in test1: # 繰り返しの回数部分にリストを用いる
print(i)
前回はfor文の条件inの後ろにrange()関数を用いましたが,listを用いることもできます.リストの要素に対して繰り返し同じ操作を行うときによく使います.(実はこのような処理ができる言語は少ないです.Pythonの便利な一つの特徴です)
for i in test1: # リストを繰り返し回数部分に使う
j=i**2 # test1の要素を2乗する
print(j)
リストの要素を追加することもできます.
a =[10, 20, 30, 40] # リストaを準備
b= a + [50] # リストa = [10, 20, 30, 40]の最後尾に50という要素を追加する
print(b)
リストの要素を追加するときには追加する要素もリスト([ ]で囲う)でなければなりません(リストにしないとエラーが出ます).
また、要素の置き換えも行うことが出来ます.
a[1] = "二十" # a[1]=20 → a[1]="二十"へ置き換える
print(a)
リストの要素を削除する際にはdel文を使う.
del a[1] # del文を用いてリストの要素a[1]を削除
print(a)
空のリストを用いて,リストを作成することも良くある.
odd = [] # 空のリストを用意
for i in range(10): # 0~9まで繰り返す
if i % 2 == 1: # iが奇数の場合のみ下のブロックを実行
print(i)
odd += [i] # odd=odd+[i]を実行 リストの要素を追加
print(odd)
プログラムではリストの要素を検索することが良くあります.特定の要素の検索はinという演算子を使います.検索した文字列がリストの中に入っていれば"Ture",入っていなければ"False"を返染ます.
subjects = ["数理工学入門", "微積分1", "線形代数1"] # リストを用意
"微積分1" in subjects # in演算子を用い,リストsubjectsに"微積分1"が含まれているか検索
"情報処理" in subjects # in演算子を用い,リストsubjectsに"情報処理"が含まれているか検索
空のリストを用意しforループを用いてフィボナッチ数列を第10項まで計算し,リストとして出力しなさい.
\begin{equation}
f(n+2)=f(n+1)+f(n), \
f(1)=1, f(2)=1
\end{equation}
ヒント:第5項までのリストは[1, 1, 2, 3, 5]となります.
様々なプログラムでリストの要素の数を使う事があります.その場合len()関数が使われます(len関数は「リスト」のみならず,この後やる「ディクショナリ」「文字列」「タプル」などでも使えます).
a=[10, 30, 40] # リストを用意
print(len(a)) # len()関数でリストaの要素数を返す
リストaは4つの要素を持つことが分かります.例えば,下記のプログラムはリスト化された身長の平均を求めるプログラムです.
# 平均身長を求めるプログラム1
shincho = [152, 183, 170, 155, 158, 172, 180, 175] # 身長のデータリストを用意
wa = 0 # 和を代入する変数の初期化
for i in shincho: # 繰り返し回数としてlistを利用
wa += i # リストの要素を足し合わせる wa = wa +i と同じ意味
print("平均身長は", wa/len(shincho)) # waをリストの要素数で割り平均身長を計算
実は,Pythonには和を求める関数sum()が用意されているので上のプログラムは下のようにも書けます.
# 平均身長を求めるプログラム2
shincho = [152, 183, 170, 155, 158, 172, 180, 175]
list_ave = sum(shincho)/len(shincho) # sum()関数を用い和を計算,lin()関数を用い要素数を計算,それらから平均身長を計算
print("平均身長は", list_ave)
len(),sum(),の他にも用意されている関数があります(xxxにはリスト名が入ります).
| 関数 | 動作 |
|---|---|
| `len(xxx)` | リストの要素の数を求める. |
| `sum(xxx)` | 要素の合計値を求める |
| `max(xxx)` | 最大値をとる要素を返す |
| `min(xxx)` | 最小値をとる要素を返す |
リストを取り扱う場合に良く使う操作があります.例えば,「リストの要素を順番に並べ替えたり」「リストの中からある要素を取り除く」操作の事です.このような操作はリスト型独自の関数として初めから準備されてます.例えば,下記は「リストの要素を順番に並べ替える」プログラムになります.
# リストの要素を並び替えるプログラム
test1 = [3, 20, -2, 5, 6] # リストを用意
test1.sort() # sort()メソッドを用いtest1を小さい値順に並べ替える
print(test1)
リストtest1の後ろに.sort()というのを付け加えています.これを付け加えることでtest1の要素を小さいものから順に並べ替えることができます.このように,ある変数型が独自に持ってる関数のことをメソッドと言います.Pythonはほかの言語と比較しこのメソッドを標準(インストール段階)で非常に多く用意しています.メソッドはライブラリというものの中で定義されており,追加することでさらに便利なメソッドを使用することが可能になります.Pythonでは特に,科学技術計算と統計解析のライブラリが豊富なことで有名です.従って,これらのメソッドを用いる事で比較的容易にプログラムを作成することができるのです.(Pythonのライブラリの豊富さは"Battery Included"というプログラム言語思想に基づいてます)
他のメソッドを見てみましょう..append()はリストに要素を追加するメソッドです.
リストに追加したい要素を()内に引数として渡しします.
test2 =[1, 2, 3, 4, 5]
test2.append(10) # append()メソッドを用いtest2に10を付け加える
print(test2)
その他のlist型のメソッドの一部は下記のとおりです.
| メソッド | 動作: xxx=["xyz", "def", "abc"]として,書き方の例を示す. |
|---|---|
| xxx.sort() | リストを昇順(数字の若い順,A-Z順)に並び替え,xxxリスト自体を書き換える. |
| xxx.remove(取り除く要素) | xxxリストから()内に指定された要素を取り除く.例:xxx.remove("def") |
| xxx.append(追加する要素) | xxxリストの末尾に()内に指定された要素を追加する.例:xxx.append("hij") |
| xxx.extend(追加するリスト) | 追加するリストの要素を連結する.タプルの形で与えることもできるが,その場合,その要素だけ変更ができない.例:xxx.extend(["klm","hij"]) |
| xxx.pop(インデックス数) | xxxリストの指定された要素をひとつだけ取り除き,戻り値として取り除いた要素を返す.インデックスの数値を指定しない場合は末尾を対象に操作を行う.例:xxx.pop(0) |
| xxx.index(検索したい要素) | xxxリストの中から検索したい要素を探し出し,一番最初のインデックスの数値を返します.例:xxx.index("def") |
| `xxx.count`(数えたい要素) | xxxリストの中から数えたい要素を探し出し,要素数を返します.例:`xxx.count("def")` |
10以下の適当な正の数の組を5個入れたリストを用意し,任意の10以下の正の数aをキーボードから受け取りその数がリストに入っているか否かを判定するプログラムを書きなさい.プログラム名it05_学籍番号.ipynb
〆切:11/6(月)
ヒント
aを受け取る.aを比較する.aはリスト内に存在します」と出力aはリスト内に存在しない」と出力str(文字列型)については第1回目の講義で少し取り扱いましたが,ここではさらに高度な取り扱いを学びます.
実は,文字列型はリスト型と同様にインデックスを使って要素を取り出すことができます.もちろん,スライスも用いる事ができます.
mu_address = "江東区 有明 3丁目 3番 3号" # 文字列 mu_address を用意
print(mu_address[4]) # mu_addressからインデックスを用い,5番目の要素"有"を取り出す(mu_address[4]は5番目の要素を表すことに注意)
print(mu_address[4:6]) # mu_addressからスライスを用い,5番目の要素と6番目の要素"有明"を連続的に取り出す
ただし,リスト型と異なり文字列型では単純な文字の置き換えはできません.すぐ後でメソッドを用いて置き換えの様なことを行います.
mu_address[7] = "1" # 既にある文字列に新しい文字を直接代入することはできません
これはリスト型が置き換え可能な変数型(ミュータブル)であるのに対し,文字列型は置き換え可能な変数型(イミュータブル)ではないことが原因です.
文字列の長さはリスト型と同様にlen関数を使います.
len(mu_address) # 文字列 mu_addressの要素数を数える
検索についてもリスト型と同様にin演算子を用います.
"有明" in mu_address # mu_addressの要素の中に"有明"という文字列が存在するかin演算子を用いて調べる
"西東京市" in mu_address # mu_addressの要素の中に"西東京市"という文字列が存在するかin演算子を用いて調べる
次の文字列(chaplin_01)について
chaplin_01 = "Imagination means nothing without doing."
(1) 文字数を数えなさい.(len()関数)
(2) "doing"という文字列があるか判断しなさい.(in演算子)
(ちなみにこのことわざの意味は「実行のない想像力は無意味である」(by チャップリン) )
文字列には多くの「使い勝手の良い」メソッドが用意されてます.良く行う操作として,文字列の置き換えがあります.文字列の置き換えにはreplace()メソッドを使います.
mu_address.replace("江東区", "東京都江東区") # replace()メソッドを持ちいて置き換える
ここで注意することは,mu_addressの中身は変わっていない事です.
print(mu_address)
4.3.1で説明したように,文字列は置き換えができないのです.したがって,置き換えしたい場合は次のように元の変数全体を上書きすることにより置き換えます.
mu_address = "江東区 有明 3丁目 3番 3号"
mu_address = mu_address.replace("江東区", "東京都 江東区") # replace()を用いて"江東区"を"東京都 江東区"へ置き換えた文字列を,mu_addressに代入し上書きする
print(mu_address)
テキストマイニングなどデータ処理する際には,1行ずつ文字列を読み込んで文字を分割してリスト化し,そのリストを解析する事になります.そのような場合にはsplit()メソッドをを持ちます.
mu_address = "東京都 江東区 有明 3丁目 3番 3号" # 文字列を用意
add_list = mu_address.split(" ") # split()メソッドを用いて " "(半角空白)の区切り毎に文字列を分割しリストを返しadd_listへ代入
add_list
上のプログラムのようにsplit(" ")と()内で区切りの指定を行ってます.今回のケースでは(" ")「半角空白」で区切りの指定を行っていることが分かります.
split()と逆にリストの要素を連結し文字列として出力するメソッドjoin()も良く使います.
mu_address_new = " ".join(add_list) # join()メソッドを用いてリスト(add_list)の要素を" "(半角空白)区切りで連結する
mu_address_new
上のプログラムのようにリスト要素(今回の例ではadd_listの要素)の連結部分の文字列(今回は半角空白)を" "としjoin(add_list)でadd_listの要素を半角空白でつなぎ文字列としてmu_address_newに代入されてます.
| メソッド | 動作 `S="AOaOA"`として,書き方の例を示す. |
|---|---|
| `S.find`(検索したい文字列) | 文字列`S`の先頭から検索を行い,「検索したい文字列」を探します.最初に見つかった位置を`0`から始まるインデックスとして返します.見つからなかった場合に「`-1`」を返します.例:`S.find("A")` |
| S.index(検索したい文字列) | findと同じ用に動作するが,見つからなかった場合にエラーを返します.例:S.index("A") |
| S.split(区切り文字) | 文字列Sを区切り文字で区切り,文字列のリストを作って返します.例:S.split("O") |
| S.join(リスト) | リストの要素の間に文字列Sを挟んで一つの文字列に統合する.リストではなく,タプルの形で与えることもできる.例:S.join(["X","Y","Z"]) |
| S.upper() | 文字列の小文字を大文字にする.例:S.upper() |
| S.lower() | 文字列の大文字を小文字にする.例:S.lower() |
(この問題は少し難しいです)次の文字列(jordan_01)をプログラムを用いてstepが何個あるか判断するプログラムを作りなさい(大文字小文字の区別はしません).
jordan_01 = "Step by step. I can’t see any other way of accomplishing anything."
(ちなみにこのことわざの意味は「一歩ずつ着実に立ち向かう事.何かを達成する場合に取るべきこれ以外の方法はない.」(by Michael Jordan))
「計算結果を保存する」,「保存した計算結果を読み込みデータ処理する」,「テキストマイニングする」など様々な場合において,プログラム内でファイルの読み書きを行います.Pythonではファイル処理するために組み込み型の一つであるファイルオブジェクト(ファイル型)が用意されてます.ここでは,ファイル処理について基本的なことを学びます.
まずこのページからit04_01data.txtをダウンロードし"C:\Users\「ユーザー名」\Documents\workspace\python"ディレクトリに置いてください.以下のプログラムではit04_01data.txtに書かれているすべての文字列データを読み込みます.
it05_01date.txtを読み込み
読み込んだデータin_file1をchara1(文字列変数)に代入し
chara1をコマンドプロンプトに出力し
in_file1を閉じる
という手続きになります.
in_file1 = open("it04_01data.txt", "r", encoding="utf-8") # it04_02data.txtを読み込みファイルオブジェクトin_file1へ代入
chara1 = in_file1.read() # ファイルオブジェクトから文字列をchara1へ代入
print(chara1)
in_file1.close() # ファイルオブジェクトin_file1を閉じる
ファイルを読み書きする際にはopen()関数を用います.
open("ファイル名", モード, [エンコード])
今回のケースではファイル名は"it04_01data.txt",モードは読み込みモード"r",エンコード(文字コードの種類)はencoding="utf-8"と指定してます(省略できデフォルトは"utf-8"です).in_file1はファイルオブジェクトと呼ばれるものです.read()は文字列を返すファイル型のメソッドです.最後に,close()メソッドを用いてファイル型を閉じて終了します.
ファイル全てを文字列として扱うのではなく,1行ずつ文字列を取り扱いたい場合がよくあります.その場合,下記のようにループを用います(下記のプログラムは1行毎に読み取り,文章をリスト化してます).
#it04.py
in_file2 = open("it04_01data.txt", "r")
list1=[] # 空のリストlist1を用意
for line in in_file2: # in_file2の要素をループ変数としてくり返す
list1.append(line) # list1へ要素in_file2の要素を付け加える
print(list1)
in_file2.close()
各行の最後に書かれている「\n」は「改行記号」になります.「改行記号」や「タブ」などは(文章の形を制御する)コントロールコードと呼ばれるもので,「\n」のようなエスケープ記号を用いて文字列に埋め込むことができます.
| エスケープ記号 | 説明 |
|---|---|
| `\n` | 改行 |
| `\t` | 水平タブ |
| `\f` | 改ページ |
| `\'` | シングルクオテーション |
| `\"` | ダブルクオテーション |
| `\;` | バックスラッシュ |
| `\0` | Null(ヌル)文字 |
続いてファイルへの書き出しを行います.
in_file3を用意する.in_file3に書きだす(けど,すぐに全部書き出されていない)in_file3に今すぐ全部書きだすin_file3を閉じるという手続きになります.
in_file3 = open("it04_02data.txt", "w") # it04_02data.txtを書き出しモードで開きin_fileへ代入(ファイルがない場合は新しくファイルを作る)
in_file3.write("「情報処理はとても簡単,簡単,簡単,簡単♪」\n「んなわけあるか!!」") # in_file3へ書き込み
in_file3.flush() # in_file3への書き込みをすぐに実行する
in_file3.close()
"C:\Users\「ユーザー名」\Documents\workspace\python"ディレクトリに"it04_02data.txt"ファイルが出来ましたのでメモ帳で開いてみてください.
書き出しの場合も読み出しと同様open()関数を用います.ただし,書き出しモード"w"を指定します.なお,ファイルが存在しない場合は新しいファイルが作成されます.書き込みはwrite()メソッドを用いて行います.write()メソッドは文字列を書きこむことに注意してください.また,読み出しと異なり書き出しの場合flush()メソッドを用い,すべてのデータを書きだす必要があります(正確にはバッファに残っているデータを書きだしバッファを空にする).最後に,close()メソッドを用いてファイルオブジェクトを閉じます.
it04.pyをもちいたリストには「空の行(\nだけの行)」や「\nが含まれた文字列」があります.it04.pyを改良し,it04_01data.txtを読み込み「空の行(\nだけの行)」や「\nが含まれた文字列」を取り除いたリストを出力するプログラムを作成しなさい.
出力結果(空の行(\nだけの行)」や「\nが含まれた文字列」が取り除かれ,リストの要素が文字列だけになっていることに注目)
['Dear Dr. Hatena,', 'We shall be glad to publish this manuscript in Physical Review E.', 'However, your current figures and/or manuscript do not conform to the', 'style of this journal for the reasons mentioned below.', 'We are holding your manuscript in this office. Please upload suitably', 'corrected original figures and/or manuscript as soon as possible.', 'Details on how to resubmit as well as preferences for file types are', 'available at', 'http://publish.aps.org/authors/web-submission-guidelines-physical-review', 'Once these problems are resolved, we shall then proceed with publication.', 'Yours sincerely,', 'Lupin III', 'Managing Editor', 'Physical Review E', 'Email: pre@aps.org', 'http://pre.aps.org/']
数値計算やデータ解析をする場合に一部の文章に任意の文字列を差し込む処理を行う事が良くあります.format()メソッドは波カッコ{ }を用いて,文章中に差し込む位置を指定します.具体例は下記のとおり.
"数理工学科の講義の中で好きな講義は{}です.".format("数理工学入門") # format()メソッドを用い{ }内に"数理工学入門"を差し込む
{}の中に番号を付けることで,幾つかの任意の文字列を順番に差し込む事ができます.
line = "数理工学科の講義の中で好きな講義は{0}と{1}ですが,どちらかというと{0}の方が好きです."
line.format("数理工学入門", "情報処理")# {0}, {1}のように番号を付けることで複数の文字列を差し込むことができる
文字列フォーマットは数値計算結果を文字列としてファイル出力する際によく使用します.
in_file4 = open("it04_03data.txt", "w")
for t in range(1, 11): # 1~10までのループ
x = 2*t # x=2tを計算
in_file4.write("{0} {1}\n".format(t, x)) # [t, x]の組の結果をit04_03data.txtに出力
in_file4.flush()
in_file4.close()
数式(数理モデル)の結果をファイルに出力することも今後よく使います.下記は(真空中の)自由落下の式です. \begin{equation} x(t) = \frac{1}{2}gt^2 \end{equation} $x$は初めの位置($x_0 = 0$)から$t$秒後に落下した距離(単位$m$)を表します.$g$は重力加速度($9.8 m/s^2$)と呼ばれるものです.0秒から999秒までに落下した距離を計算し,次の出力結果をit04_08.txtとして出力するプログラムを作成しなさい.
解答例
t m
0 0.0
1 4.9
2 24.5
3 68.6
4 147.0
5 269.5
6 445.9
7 686.0
8 999.6
9 1396.5
10 1886.5
11 2479.4
12 3185.0
13 4013.1
14 4973.5
15 6076.0
16 7330.4
17 8746.5
it04_04data.txtは「吾輩は猫である」の第1章である.この文章の中に「猫」は何匹居るか? it04_04data.txtを読み込み猫の数を数えるプログラムを2つ作成しなさい.
2つのプログラムを1つのプログラムとしてまとめ,プログラム名it06_学籍番号.ipynb
〆切 11/20(月)