Pythonにはinsertやappend、extendなど元の配列自体を書き変えるメソッドが複数用意されています。
元の配列自体を書き変えるメソッドのことを破壊的メソッドと呼びます。
ここでは、Pythonの配列処理で頻繁に使用する主要な破壊的メソッドとその使い方を実例でまとめています。
insertメソッド
インデックス番号を指定して値を挿入する。
insert x y
└ インデックス番号xにyを挿入する。
└ xは整数
└ もとの要素以上(以下)のインデックス番号を指定すると、末尾(先頭)に追加。
a = [1,2,3]
#0番目に「10」を追加
a.insert(0,10)
print(a)
#出力
[10, 1, 2, 3]
▼存在しないインデックス番号を指定した場合(正の数値)
a = [1,2,3]
#10番目に「20」を追加
a.insert(10,20)
print(a)
#出力
[1, 2, 3, 20]
インデックス番号10を指定しているが、対象のlistの最大が10未満のため、末尾に追加される。
▼存在しないインデックス番号を指定した場合(負の数値)
a = [1,2,3]
#-10番目に「30」を追加
a.insert(-10,30)
print(a)
#出力
[30, 1, 2, 3]
appendメソッド
末尾に要素を追加する。(指定した内容を塊として追加)
append(追加する値)
a=[1,2,3]
a.append('a')
print(a)
##出力
[1, 2, 3, 'a']
似たメソッドにextendがあります。appendとextendの違いは複数の文字列や複数の要素が入った配列を指定したときや、追加する要素に自分自身を指定した場合の挙動です。
▼文字列や配列は塊として入る。(※extendとの違い)
a=[1,2,3]
a.append("abcde")
print(a)
##出力
[1, 2, 3, 'abcde']
a=[1,2,3]
b=[4,5,6]
a.append(b)
print(a)
##出力
[1, 2, 3, [4, 5, 6]]
▼自分自身は追加できない(※extendとの違い)
a=[1,2,3]
a.append(a)
print(a)
#出力
[1, 2, 3, [...]]
▼親オブジェクトが1次元大きい場合
a=[[1,2,3]]
b=[4,5,6]
a.append(b)
print(a)
#出力
[[1, 2, 3], [4, 5, 6]]
同一次元になります。
extendメソッド
末尾に要素を追加。(1文字づつ追加)
extend(追加する要素)
└ 1文字つづ追加
└ 文字列は分解される
a=[1,2,3]
b=[4,5,6]
a.extend(b)
print(a)
#出力
[1, 2, 3, 4, 5, 6]
a=[1,2,3]
a.extend("abcde")
print(a)
#出力
[1, 2, 3, 'a', 'b', 'c', 'd', 'e']
▼自分自身も追加できる(※appendとの違い)
a=[1,2,3]
a.extend(a)
print(a)
#出力
[1, 2, 3, 1, 2, 3]
▼多次元の場合は塊で結合
a=[1,2,3]
b=[[4,5,6],[7,8,9]]
a.extend(b)
print(a)
#出力
[1, 2, 3, [4, 5, 6], [7, 8, 9]]
a=[[1,2,3]]
b=[[4,5,6],[7,8,9]]
a.extend(b)
print(a)
#出力
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
スライスで追加
メソッドではありませんがスライスで範囲を指定して挿入することも可能です。
スライスの特徴(extendとappendを併せ持つ)
・同一階層に追加
・塊で追加(1文字づつ分解しない)
スライスの使い方
list[x:x]=追加する要素
└ x:追加したいインデックス番号
└ スライス範囲は同一範囲を指定 ※違うと置き換えが発生する
スライスの実例
a=[1,2,3]
a[1:1]=['aaa','bbb']
print(a)
#出力
[1, 'aaa', 'bbb', 2, 3]
▼インデックス番号のマイナス指定も可能
a=[1,2,3]
a[-1:-1]=['aaa','bbb']
print(a)
#出力
[1, 2, 'aaa', 'bbb', 3]
末尾の要素から、0, -1, -2,,,番となる。
▼範囲外の指定
・プラス側に大きい場合は末尾に追加。
・マイナス側に大きい場合は冒頭に追加。
a=[1,2,3]
a[10:10]=['aaa','bbb']
print(a)
#出力
[1, 2, 3, 'aaa', 'bbb']
a=[1,2,3]
a[-10:-10]=['aaa','bbb']
print(a)
#出力
['aaa', 'bbb', 1, 2, 3]
スライスによる要素の書き換え
list[x:y]=追加する要素
└ x~y-1までの範囲を置換。
└ yは含まない
▼n番目の要素を置き換えるlist[n:n+1]
a=[1,2,3,4,5,6,7]
a[2:3]=['aaa','bbb']
print(a)
##出力
[1, 2, 'aaa', 'bbb', 4, 5, 6, 7]
▼まとめて置き換える
a=[1,2,3,4,5,6,7]
a[0:5]=['aaa','bbb']
print(a)
##出力
['aaa', 'bbb', 6, 7]
範囲0~4番目を置換。
▼範囲外を指定した場合
a=[1,2,3,4,5,6,7]
a[0:10]=['aaa','bbb']
print(a)
#出力
['aaa', 'bbb']
▼範囲外を指定した場合2
a=[1,2,3,4,5,6,7]
a[10:20]=['aaa','bbb']
print(a)
#出力
[1, 2, 3, 4, 5, 6, 7, 'aaa', 'bbb']
▼すべて置換
a=[1,2,3,4,5,6,7]
a[:]=['aaa','bbb']
print(a)
#出力
['aaa', 'bbb']
removeメソッド
値を指定して最初の要素を削除。
remove(削除する要素)
└ 複数ある場合は、最初の要素のみ削除
└ 存在しない値はエラー
a = [1,2,3]
a.remove(1)
print(a)
#出力
[2, 3]
▼指定値が複数ある場合
a = [1,2,3,1,2,3,1,2,3]
a.remove(2)
print(a)
#出力
[1, 3, 1, 2, 3, 1, 2, 3]
最初の要素のみ削除。
popメソッド
popメソッドを使うと、インデックス番号を指定して削除できます。
pop(インデックス番号)
└ 該当するインデックス番号の値を削除
└ 範囲外の番号はエラー
a = [1,2,3]
a.pop(2)
print(a)
#出力
[1, 2]
インデックス番号2(値3)を削除。
▼範囲外はエラー
a = [1,2,3]
a.pop(-10)
print(a)
#出力
IndexError: pop index out of range
clearメソッド
clearメソッドを使うと指定した要素の中身がすべて消えます。入れ物(変数)は残ります。
clear()
└ カッコ必須
└ 引数なし ※引数があるとエラー
a = [1,2,3]
a.clear()
print(a)
##出力
[]
del文
list用のメソッドではありませんが、del文でも要素の削除ができる。
del listオブジェクト[インデックス番号]
└ インデックス番号はスライスで指定
▼インデックス番号を指定して削除
a=[1,2,3]
del a[0]
print(a)
##出力
[2, 3]
popメソッドと同じ処理になります。
▼範囲を指定して削除
[開始値:終わり値]
└ 終わり値は削除処理しない。(未満)
インデックス番号3~4(5は含まない)を削除する場合は次のようにします。
b=[1,2,3,4,5,6,7,8,9]
del b[3:5]
print(b)
##出力
[1, 2, 3, 6, 7, 8, 9]
▼すべて削除する方法
全ての要素を削除する場合は、スライスで全範囲[:]
を指定します。
a=[1,2,3]
del a[:]
print(a)
##出力
[]
clearメソッドと同じ処理です。
sortメソッド
昇順ソート
sort()
└ デフォルト(reverse=False)
└ 引数不要 ※入れるとエラー
a=[4,2,10,-10]
a.sort()
print(a)
##出力
[-10, 2, 4, 10]
a=[]
a.extend("egkacb")
a.sort()
print(a)
##出力
['a', 'b', 'c', 'e', 'g', 'k']
降順ソート
sort(reverse=True)
└ オプションで「reverse=True」を指定
a=[4,2,10,-10]
a.sort(reverse=True)
print(a)
##出力
[10, 4, 2, -10]
reverseメソッド
listの要素を反転させる。
※降順ソートとは異なる
a=[4,2,10,-10]
a.reverse()
print(a)
##出力
[-10, 10, 2, 4]
a=[]
a.extend("egkacb")
a.sort()
print(a)
##出力
['b', 'c', 'a', 'k', 'g', 'e']
破壊的メソッドの注意点
変数に代入できない。
元のオブジェクトを変更しているため。例えば、
・a.append()が参照しているのは、「a」自身。
・「a.append()」というものは存在しない。
a = [1,2,3]
b = a.append(4)
print(b)
##出力
None
存在しないものを変数bに代入しているので、bの中身はNone。
更に要素を追加したい場合は、再度a自体をいじる。
破壊的メソッドを自分で作る方法
insert, print, remove, append, sort, pop, reverseのいずれかが入力されたときに、既定のメソッドの処理に該当する処理を自分で作成することもできます。
コードの内容
記述方法はいくつかあります。
パターン1
if __name__ == '__main__':
n = int(input())
lists = [input() for _ in range(n)]
arr=[]
for i in lists:
arr.append(i.split())
res=[]
for j in arr:
if len(j) >= 2:
a=int(j[1])
if len(j) >=3:
b=int(j[2])
#各処理
if j[0]=="insert":
res.insert(a, b)
if j[0]=="print":
print(res)
if j[0]=="remove":
res.remove(a)
if j[0]=="append":
res.append(a)
if j[0]=="sort":
res.sort()
if j[0]=="reverse":
res.reverse()
if j[0]=="pop":
res.pop()
ans=res
パターン2
n = int(input())
l = []
for _ in range(n):
s = input().split()
cmd = s[0]
args = s[1:]
if cmd !="print":
#文字列で引数部を作成し、cmdと結合する
cmd += "("+ ",".join(args) +")"
#式を実行(カッコ内は文字列)
eval("l."+cmd)
else:
print (l)
・eval("式")
└ 引数に式をいれる ※文ではない
引数で与えられた文字列の式を実行する。
・例:eval(“list.insert(2,5)”)
パターン1とパターン2のどちらも入力と出力は次のようになります。
▼sample input
12 #入力するコマンド数
insert 0 5
insert 1 10
insert 0 6
print
remove 6
append 9
append 1
sort
print
pop
reverse
print
▼sample output
[6, 5, 10]
[1, 5, 9, 10]
[9, 5, 1]