【collections.deque】Pythonでリストよりも高速にデータを追加・削除する方法

本記事は、collections.dequeの基本的な使い方を解説しています。引数やメソッドなどの説明には、その特徴が分かるようなコード例があるので、参考にしながら機能を確認していただければと思います。
本記事は、こちらのドキュメントを参考にしているため、pythonのバージョンによっては挙動が異なる場合があります。その場合は、ドキュメントを参照してください。
collectionsには、他にどんな関数があるのか気になる方は、こちらの記事にまとめています。

dequeとは
Dequeは、スタックやキューのように、要素を先頭や末尾から追加したり削除したりすることができるデータ構造です。Deque は複数のスレッドから同時にアクセスされても正しい結果を保証されており、先頭や末尾の両方から高速に要素を追加したり削除できるため、高速でメモリ効率が良いです。また、Deque のサイズは制限することができ、サイズが制限されている場合は、新しい要素を追加すると制限を超える分だけ反対側から要素が削除されます。Dequeは、トランザクションの追跡や最近使用した要素を保持するデータプールなどにも使用できます。
collections.dequeの引数
collections — deque コンテナデータ型 — Python 3.11.0b5 ドキュメント
collections.dequeには、以下の引数があります。
- iterable
- maxlen
iterable
初期値として追加する要素を含む反復可能なオブジェクトです。list や tuple などが指定できます。省略した場合、空の deque オブジェクトが作成されます。
from collections import deque
# 空の deque オブジェクトを作成
d1 = deque()
print(d1) # deque([])
# 初期値として [1, 2, 3] を追加した deque オブジェクトを作成
d2 = deque([1, 2, 3])
print(d2) # deque([1, 2, 3])maxlen
deque の最大サイズを表す整数値です。指定した場合、deque のサイズは最大でも maxlen に制限されます。省略した場合、deque のサイズは制限されず、任意のサイズまで大きくなります。
# 最大サイズが 5 の deque オブジェクトを作成
d3 = deque(maxlen=5)
print(d3) # deque([], maxlen=5)
# 初期値として [1, 2, 3, 4, 5] を追加し、最大サイズが 3 の deque オブジェクトを作成
d4 = deque([1, 2, 3, 4, 5], maxlen=3)
print(d4) # deque([3, 4, 5], maxlen=3)collections.dequeのメソッド
Dequeクラスには、次のようなメソッドがあります。
append(x): deque の末尾に要素xを追加します。appendleft(x): deque の先頭に要素xを追加します。clear(): deque のすべての要素を削除します。copy(): deque の複製を返します。count(x): deque 中の要素xの個数を返します。extend(iterable): deque の末尾にiterableのすべての要素を追加します。extendleft(iterable): deque の先頭にiterableのすべての要素を追加します。ただし、順序は逆になります。index(x[, start[, stop]]): deque 中の最初のxのインデックスを返します。引数startやstopを指定することで、検索範囲を指定することができます。insert(i, x): deque のインデックスiの位置に要素xを挿入します。pop(): deque の末尾の要素を削除して返します。popleft(): deque の先頭の要素を削除して返します。remove(value): deque 中の最初のvalueを削除します。reverse(): deque の要素を逆順に並べ替えます。rotate(n=1): deque の要素を右にn個分回転させます。負の値を指定すると、左に回転させます。
append(x)
append() メソッドは deque の末尾に要素を追加することができます。
次のコードでは、文字列 apple を deque の末尾に追加しています。
from collections import deque
# dequeを作成
d = deque(["banana", "orange"])
# 末尾に要素を追加
d.append("apple")
print(d) # deque(['banana', 'orange', 'apple'])複数の要素を右から追加したい場合は、後述のextend(iterable)を使用しましょう。
appendleft(x)
appendleft() メソッドは deque の先頭に要素を追加することができます。
次のコードでは、文字列 grape を deque の先頭に追加しています。
from collections import deque
# dequeを作成
d = deque(["banana", "orange"])
# 先頭に要素を追加
d.appendleft("grape")
print(d) # deque(['grape', 'banana', 'orange'])複数の要素を左から追加したい場合は、後述のextend(iterable)を使用しましょう。
clear()
clear() メソッドは deque のすべての要素を削除することができます。
次のコードでは、deque の要素をすべて削除しています。
from collections import deque
# dequeを作成
d = deque(["banana", "orange", "apple"])
# dequeのすべての要素を削除
d.clear()
print(d) # deque([])空のdequeの要素を削除してもエラーにはなりません。
from collections import deque
# dequeを作成
d = deque()
# dequeのすべての要素を削除
d.clear()
print(d) # deque([])copy()
copy()メソッドは、そのdequeオブジェクトの複製を作成します。この複製は、元のdequeオブジェクトとは別のオブジェクトとして扱われます。つまり、元のdequeオブジェクトを変更しても、複製には影響しません。
次のコードでは、deque d の複製を作成しています。
from collections import deque
# リストをdequeの中身として使用
fruits = ["banana", "orange"]
d = deque(fruits)
# dequeの複製を作成
d_copy = d.copy()
# リストの末尾に要素を追加
fruits.append("apple")
# dequeの複製の中身は変わっていない
print(d_copy) # deque(['banana', 'orange'])上記のコードでは、リストfruitsをdequeオブジェクトdの中身として使用しています。その後、dの複製を作成し、それをd_copyに代入しています。最後に、リストfruitsの末尾に要素を追加していますが、これはd_copyには影響しません。そのため、d_copyを表示すると、元のdの中身であるbananaとorangeのみが表示されます。
count(x)
count() メソッドは deque 中の要素 x の個数を返します。
次のコードでは、deque 中の文字列 banana の個数を数えています。
from collections import deque
# dequeを作成
d = deque(["banana", "orange", "apple", "banana"])
# deque中の"banana"の個数を数える
count = d.count("banana")
print(count) # 2extend(iterable)
extend() メソッドは deque の末尾に iterable のすべての要素を追加します。
次のコードでは、リスト fruits のすべての要素を deque の末尾に追加しています。
from collections import deque
# dequeを作成
d = deque(["banana", "orange"])
# リストを作成
fruits = ["apple", "grape"]
# dequeの末尾に要素を追加
d.extend(fruits)
print(d) # deque(['banana', 'orange', 'apple', 'grape'])extendleft(iterable)
extendleft() メソッドは deque の先頭に iterable のすべての要素を追加します。ただし、順序は逆になります。
次のコードでは、リスト fruits のすべての要素を deque の先頭に追加しています。
from collections import deque
# dequeを作成
d = deque(["banana", "orange"])
# リストを作成
fruits = ["apple", "grape"]
# dequeの先頭に要素を追加
d.extendleft(fruits)
print(d) # deque(['grape', 'apple', 'banana', 'orange'])index(x[, start[, stop]])
index() メソッドは deque 中の最初の x のインデックスを返します。引数 start や stop を指定することで、検索範囲を指定することができます。
次のコードでは、deque中の文字列orangeのインデックスを検索しています。
from collections import deque
# dequeを作成
d = deque(["banana", "orange", "apple", "grape"])
# deque中の"orange"のインデックスを検索
index = d.index("orange")
print(index) # 1次のコードでは、deque のインデックス2以降の文字列 orange のインデックスを検索しています。
from collections import deque
# dequeを作成
d = deque(["banana", "orange", "apple", "orange", "grape"])
# dequeのインデックス2以降の"orange"のインデックスを検索
index = d.index("orange", 2)
print(index) # 3insert(i, x)
insert() メソッドは deque のインデックス i の位置に要素 x を挿入します。
次のコードでは、deque のインデックス 1 の位置に文字列 cherry を挿入しています。
from collections import deque
# dequeを作成
d = deque(["banana", "orange", "apple"])
# dequeのインデックス1の位置に要素を挿入
d.insert(1, "cherry")
print(d) # deque(['banana', 'cherry', 'orange', 'apple'])pop()
pop() メソッドは deque の末尾の要素を削除して返します。
次のコードでは、deque の末尾の要素を削除しています。
from collections import deque
# dequeを作成
d = deque(["banana", "orange", "apple"])
# dequeの末尾の要素を削除
item = d.pop()
print(item) # apple
print(d) # deque(['banana', 'orange'])popleft()
popleft() メソッドは deque の先頭の要素を削除して返します。
次のコードでは、deque の先頭の要素を削除しています。
from collections import deque
# dequeを作成
d = deque(["banana", "orange", "apple"])
# dequeの先頭の要素を削除
item = d.popleft()
print(item) # banana
print(d) # deque(['orange', 'apple'])remove(value)
remove() メソッドは deque 中の最初に登場する値 value を削除します。
次のコードでは、deque 中の文字列 orange を削除しています。
from collections import deque
# dequeを作成
d = deque(["banana", "orange", "apple"])
# deque中の"orange"を削除
d.remove("orange")
print(d) # deque(['banana', 'apple'])reverse()
reverse() メソッドは deque の要素を逆順に並べ替えます。
次のコードでは、deque の要素を逆順に並び替えています。
from collections import deque
# dequeを作成
d = deque(["banana", "orange", "apple"])
# dequeの要素を逆順に並び替え
d.reverse()
print(d) # deque(['apple', 'orange', 'banana'])rotate(n=1)
rotate() メソッドは deque の要素を右に回転させます。引数 n を指定することで、回転する個数を指定することができます。
次のコードでは、deque の要素を 1 個右に回転させています。
from collections import deque
# dequeを作成
d = deque(["banana", "orange", "apple"])
# dequeの要素を1個右に回転
d.rotate(1)
print(d) # deque(['apple', 'banana', 'orange'])nが負の場合は、要素を左に回転させることになります。例えば、n=-1の場合は次のようになります。
from collections import deque
# dequeを作成
d = deque(["banana", "orange", "apple"])
# dequeの要素を1個左に回転
d.rotate(-1)
print(d) # deque(['orange', 'apple', 'banana'])まとめ
collections.dequeは、リストのように使える双方向のキューです。dequeを使うことで、データを効率的に入出力することができます。また、dequeには、リストにはない特有のメソッドがあるため、より柔軟にデータを扱うことができます。dequeを使いこなすことで、Pythonでのデータ処理がよりスムーズになる場合もあるので、是非覚えておきましょう!

コメント