pythonのリスト操作
pythonのlist型はよく使うのに覚えることがたくさん。
調べる手間を省きたいので備忘録です。
list型の概要
・シーケンス型の一つで、iterable
・numpyのndarrayなどの配列と違い、バラバラなメモリに紐つけで末尾追加が可能。
・要素(element)は数値に限らず、あらゆる型のオブジェクト。型の混在も可能
・list型のオブジェクトも要素になる。 [[1, 2], [3, 4], [5, 6]]
・index指定で要素を特定できる。
・多次元のlistの要素は list1[0][1]などで表し、左側の[0]が外側を表す。
・スライスが使用できる。
スライスは範囲を超えてもエラーが出ない。
・文字列と違い、スライス代入ができる。 list1[1:2] = [6, 7, 8, 9]
・listという変数名を使うとbuilt-inのlist関数を隠蔽してしまう。
list = [1, 3, 5] list(range(5)) #エラー:'list' object is not callable
隠蔽してしまったらdel listとすることでローカルのlistが削除され、もとに戻る
○リストの要素数 len(list1)
list1 = [[1, 2, 3], [4, 5, 6]] len(list1) #2 外側の要素数(2次元配列の列の数) len(list1[0]) #3 内側の要素数(2次元配列の行の数)
リストの生成
list1 = [1, 3, 5] #[1, 3, 5] list2 = "Hello world".split() #['Hello', 'world'] list3 = list("Hello") #['H','e','l','l','o'] list4 = list(range(5)) #[0, 1, 2, 3, 4] list5 = list(map(abs, range(-5, 0)))#[5, 4, 3, 2, 1] #list0 = list(0) #エラー:数値はiterableではない list6 = [0, 1, 2, 3, 4, 5, 6][1::2] #[1, 3, 5] list7 = list6[::-1] #[5, 3, 1] list8 = list7.copy() #[5, 3, 1] list9 = [i*5 for i in range(5)] #[0, 5, 10, 15, 20]
注意:
list2 = list1 とすると、list2とlist1が同じオブジェクト(同じアドレス)を参照する。
そのため、一方の要素を変更するともう一方の要素まで変更されてしまう。
list1 = [1, 3, 5] list2 = list1 print(list1, list2) #[1, 3, 5] [1, 3, 5] list2[0] = 10 #list2の0番要素を10にすると print(list1, list2) #[10, 3, 5] [10, 3, 5]
回避方法:
・list2 = list1.copy()
・list2 = list(list1)
・list2 = list1[:]
・map()やfilter()などを使う
追加、結合、挿入
list1 = [1, 3, 5] list4 = list(range(5)) list1.append(10) # [1, 3, 5, 10] list1[len(list1):] = [7]# [1, 3, 5, 7] list1.append([10, 11]) # [1, 3, 5, [10, 11]] list1.extend([10, 11]) # [1, 3, 5, 10, 11] list1.extend(list4) # [1, 3, 5, 0, 1, 2, 3, 4] list1 += list4 # [1, 3, 5, 0, 1, 2, 3, 4] list1 *=3 # [1, 3, 5, 1, 3, 5, 1, 3, 5] list1.insert(2, 10) # [1, 3, 10, 5] 2番要素の前に10を挿入 list1[2:2] = [10, 11] # [1, 3, 10, 11, 5] 2番要素の前に10と11を挿入
削除
del list1[1:2] #スライスされた要素を削除 p = list1.pop() #末項を値として返し、listからは削除 p = list1.pop(0) #0番要素を値として返し、listからは削除 list1.remove(5) #最初に見つかった5を削除。位置不明のとき。存在しないとエラー del list1[:] #全要素を削除し、空のリストになる list1.clear() #全要素を削除し、空のリストになる list1 = [] #全要素を削除し、空のリストになる del list1 #list1自体を削除。メモリを解放
検索
list1 = [1, 3, 5, 7, 1, 3, 5, 7] 3 in list1 #True 3 not in list1 #False list1.index(3) #1 3という要素の初登場index list1.count(3) #2 3という要素の登場回数
ソート(並べ替え)
ソートはlist.sort()メソッドとsorted(list)関数の2つがある。
いずれも昇順(ascending order)
オプションでreverse=Trueとすると、降順(descending order)でソート
・list.sorted()メソッド
元のリスト自体を破壊的にソート。元のlistが不要なときに使う。
list型のオブジェクトのみに使える。
返り値はNone(高速化処理などで稀に使う)
・sorted(iterable)関数
元のリストは残したまま、新たなリスト型オブジェクトを作る。
対象となるのはiterableなオブジェクト(リスト型、タプル型、辞書型など)
タプル型は[0]の要素を基準に並べ替える。
・keyオプション
keyオプションは比較する前に、全要素に対する処理を行う関数を指定。
タプル型の[1]の要素を基準にしたりできる。
sortメソッドもsorted関数もkeyオプションを付けられる。
・要素の全入れ替え
list1.reverse() #リストの要素の順番をすべて逆にする。ソートではない。
list1 = list1[::-1] #リストの要素の順番をすべて逆にした新しいリストを得る。
#シンプルな並べ替え list1 = [5, 3, 1, 7] list1.sort() #[1, 3, 5, 7] 返り値はNone list1 = sorted(list1) #[1, 3, 5, 7] 返り値は[1, 3, 5, 7] list1.reverse() #[7, 5, 3, 1] 返り値はNone list1 = list1[::-1] #[7, 5, 3, 1] 返り値は[7, 5, 3, 1]
#いろいろな並べ替え list1 = ["I", "am", "a", "python"] #小文字としてソート list1.sort(key=str.lower) #['a', 'am', 'I', 'python'] list1 = [(1, "c"), (2, "a"), (3, "t")] #各タプルの2番目の要素、つまり[1]で。 list1.sort(key=lambda x:x[1]) #[(2, 'a'), (1, 'c'), (3, 't')] list1 = [3, 1, 5] list1.sort(reverse=True) #[5, 3, 1]
2番要素[1]でソートし、次に1番要素[0]でソートする場合
from operator import itemgetter list1 = [(3, "b"), (5, "a"), (7, "b"), (1, "a")] sorted(list1, key=itemgetter(1, 0)) #[(1, 'a'), (5, 'a'), (3, 'b'), (7, 'b')]
リストから重複を取り除く
list(set(list1)) #順番をきにしないとき sorted(set(list1)) #ソートしたリストのとき sorted(set(list1), key=list1.index) #初登場順を維持するとき
リストをスタックとして使う
LIFO(last in first out)として使う方法
list1 = [1, 3, 5] list1.append(7) # 末尾に追加する list1.append(9) print(list1.pop()) # 末尾から取り出す print(list1.pop())
リストをキューとして使う。
FIFO(first in first out)として使う。
pop(0)で最初の要素を取り出せるが、動作が遅いのでcollectionsのdequeを使うのがよい。
dequeはリストの両端での追加、取り出しが高速に実行できる。
from collections import deque q = deque([1, 3, 5]) q.append(7) q.appendleft(-1) print(q) # deque([-1, 1, 3, 5, 7]) print(q.pop()) # 7 print(q.popleft()) # -1 print(q) # deque([1, 3, 5])