前回までの「Python初体験」の続きです。
前回、Pythonの標準配列としてのリスト(list)を知りましたが、今回はそれの使い方(method)について学びましょう。(注)
注:などと、殊勝に書きましたが、どのようなプログラミング言語でも単純な配列(Pythonではリスト)である、一次元配列のデータ処理は大体次の通りとなります。
(1)追加、値の代入、削除
(2)検索、置換
(3)並び替え
最もプリミティブな配列は単純にデータをメモリーに並べてゆくだけになりますが、そういう単純なデータ処理は検索や並び替えの際に時間やリソースを浪費します。
現在は配列は配列データに対するポインター(メモリー上のデータ位置を指すアドレス)となり、検索や並び替えではデータそのものは参照するだけになりますし、置き換えの場合には元のデータを削除し、新しいデータを作って、そのアドレスデータを入れるだけになります。
OOPでデータと処理が統合されている場合には、配列に対するこのような操作が最初から配列オブジェクトにビルトインされています。
(1)追加、値の代入と削除
Pythonでは改めてList等の宣言は行わず、単純に配列で初期化すれば自動的にリストオブジェクトになります。
values = ['A', 'B', 'C'] #valueという変数(というか、オブジェクト)に配列であることを示す[]による初期化を行う。
この段階で、
print("修正前:", values, "(要素数:", len(values), ")") #リストには要素数を取得するメソッドにはないですね。"len(<リスト>)"関数を使います。
とすると、出力は、
修正前: ['A', 'B', 'C'] (要素数: 3 )
になります。次にデータを追加するには「insert(<位置>, <データ>)」メソッドを使います。最初の要素に111、ブービー(最後の一つ前)に999を入れると、
values.insert(0, 111)
print("修正後1:", values, "(要素数:", len(values), ")")
values.insert(3, 999)
print("修正後:", values, "(要素数:", len(values), ")")
こうなります。
修正後1: [111, 'A', 'B', 'C'] (要素数: 4 )
修正後: [111, 'A', 'B', 999, 'C'] (要素数: 5 )
データの追加にはinsertの他、append()(末尾に要素を追加)やextend()または '+' 演算子による要素の結合も可能です。
values.append(["私の", "名前は", "ysamaです"])
print("要素追加後:", values, "(要素数:", len(values), ")")
values += [16, 32, 64]
print("要素追加後:", values, "(要素数:", len(values), ")")
追加後はこうなります。
要素追加後: [111, 'A', 'B', 999, 'C', ['私の', '名前は', 'ysamaです']] (要素数: 6 )
要素追加後: [111, 'A', 'B', 999, 'C', ['私の', '名前は', 'ysamaです'], 16, 32, 64] (要素数: 9 )
ここで注意されたいのは、Pythonでは配列(リスト)に異なる型のデータを要素として混在させられることです。出力される"[]"の括りからすると、ベースは数値データで、文字列データの際に別の配列として中に入れているようです。(いずれにしてもリストオブジェクトの実体は矢張りポインターの配列のようですね。)
要素はリストオブジェクトに"[]"で、要素番号を指定すれば抽出、値の代入等が出来ます。
values[2] = 'b' #'B'を'b'に置き換えます
print("要素置換後:", values, "(要素数:", len(values), ")")
とすると、
要素置換後: [111, 'A', 'b', 999, 'C', ['私の', '名前は', 'ysamaです'], 16, 32, 64] (要素数: 9 )
となります。
最後にリストの要素の削除ですが、矢張りオブジェクトのメソッドではなく、delというコマンド文(注)を使うようです。
注:これは関数でもないです。なんか一貫していませんが...
del values[1] #削除コマンドで、valuesの2番目の要素'A'を削除します。
print("要素削除後:", values, "(要素数:", len(values), ")")
出力は、
要素削除後: [111, 'b', 999, 'C', ['私の', '名前は', 'ysamaです'], 16, 32, 64] (要素数: 8 )
となります。(なお、リストから特定の値の要素を削除する<リスト>.remove(<特定の値>)というメソッドがあるにはありますが。)
(2)検索と置換
↑で「リストオブジェクトの要素数を求めるメソッドに"count"があるのではないか?」、と最初試したらエラーになりました。
"count"メソッドはあるのですが、引数にデータを与えて合致する要素を検索し(<リスト>.count(<検索対象>))、その数を返すメソッドでした。単なる検索だけなら、その添字を教えてくれる<リスト>.index(<検索対象>)があるので、両方を組み合わせるとリスト中の検索対象のインデックスを求められます。
print("要素(999)の検索:", values.count(999))
この出力は次の通りになります。
要素(999)の検索数: 1
検索と置換は関数を定義してもよいですが、内包表記([式 for 任意の変数名 in イテラブルオブジェクト if 条件式])という方法でもできます。
def replace_array(array, s1, s2): #s1をs2に変更する関数の定義です。
for i in range(len(array)):
array[i] = array[i].replace(s1, s2)
list_string = ["私の", "名前は", "ysamaです"]; #replace()は要素がすべて文字列でないとエラーになるので
print("置換前:", list_string, "(要素数:", len(list_string), ")")
replace_array(list_string, '名前', 'あだ名')
print("置換後:", list_string, "(要素数:", len(list_string), ")")
print("置換前:", list_string, "(要素数:", len(list_string), ")")
list_string = [s.replace('あだ名', '名前') for s in list_string]
print("置換後:", list_string, "(要素数:", len(list_string), ")")
出力はこのようになります。
置換前: ['私の', '名前は', 'ysamaです'] (要素数: 3 )
置換後: ['私の', 'あだ名は', 'ysamaです'] (要素数: 3 )
置換前: ['私の', 'あだ名は', 'ysamaです'] (要素数: 3 )
置換後: ['私の', '名前は', 'ysamaです'] (要素数: 3 )
(3)並び替え
最後は要素の並び替えです。一番分かり易いのがsort(key, reverse)メソッドでしょう。keyは比較関数を指定し、reverseは正順逆順を指定します。(既定値はkey = None、reverse = False。)
この他reverse()は要素を逆順にひっくり返します。
では、では。