Python学習【365日チャレンジ!】278日目のマスターU(@Udemy11)です。
突然ですが、ジョン・フォン・ノイマンって知っていますか?
多分ほとんどの人が知らないんじゃないでしょうか?
では、アルベルト・アインシュタインは知っていますか?
こちらはほとんどの人が知っていると思います。
かの有名な相対性理論を唱え、ノーベル物理学賞を受賞した誰もが「天才」としてイメージする人物ですね。
実は、ほとんどの人が知らないジョン・フォン・ノイマンは、誰もが天才として認識しているアインシュタインが、世界一の天才だと認めた人物なんです。
現在使われているパソコンの元になった計算機は、ノイマン型と言われ、ノイマンが提唱した理論を元に作られていますし、昨日ちらっとふれた「ゲーム理論」はジョン・フォン・ノイマンが考え出した理論です。
電話帳を適当に開いたページに掲載されている電話番号の数字をすべて足した値を瞬時に計算することもできたそうで、ノイマン型のコンピューターを開発した際には、「俺の次に計算の速いやつができた」と言ったという逸話も残されているそうです。
そんな天才が考え出した「ゲーム理論」は非常に奥が深く、いろいろな学者が研究してたくさんの書籍が出版されているので、学習のための教材にはことかかないのですが、いかんせん理解するのがかなり難しいんですよね。
なので「ゲーム理論」は、のんびり学習したいと思います。
それでは今日も、Python学習を始めましょう。
昨日の復習
昨日は、文字をカウントしていろいろ便利に活用できるcollections.Counter
を学習しました。
collections.Counter
は、リストや辞書型データをカウントして、順番に表示したり、ファイルの中の文字列を抽出したりすることができました。
実際にどのような場面で活用するのかイメージがわかないのですが、今後実践に入ったときに使う場面が出てくるだろうとのことでした。
詳細については昨日の記事をごらんください。
今日は、メモリを効率よく扱って高速に処理ができるdeque
を学習します。
queueとリストとdeque
queue
は、マルチスレッド環境のメソッドがあるので、マルチスレッドで使うのがおすすめです。
リストは、インデックスの順番を指定して取り出したり値を出し入れすることに適しています。
deque
は、先頭から値を取り出したり、最後から取り出したりする時に高速に処理することができます。
それぞれに値を入れたり取り出したりしてみましょう。
import collections
import queue
q = queue.Queue()
lq = queue.LifoQueue()
l = []
d = collections.deque()
for i in range(3):
q.put(i)
lq.put(i)
l.append(i)
d.append(i)
for _ in range(3):
print('FIFO queue = {}'.format(q.get()))
print('LIFO queue = {}'.format(lq.get()))
print('List = {}'.format(l.pop(0)))
print('deque = {}'.format(d.popleft()))
print()
インポートするライブラリはcollections
とqueue
です。
4行目から順番にQueue
、LifoQueue
、リスト、deque
の順番に入れ物を定義しています。
9行目からは、それぞれの入れ物に、3つの値[0, 1, 2]
をfor
ループで回して代入しています。q
とlq
にはput
、l
とd
にはappend
を使って3つの値を入れています。
15行目からはそれぞれの入れ物の中から値を取り出して出力しています。
16行目は、ファーストインファーストアウトのqueue
からget
を使って取り出します。
17行目は、ラストインファーストアウトのqueue
から同じくget
を使って取り出します。
18行目は、リストなので、pop
を使って取り出しています。
19行目は、deque
からpopleft
を使って左から順番に取り出しています。
20行目でそれぞれのfor
ループの出力がわかりやすいようにprint()
で改行しているので、出力結果は次のようになります。
出力結果
FIFO queue = 0
LIFO queue = 2
List = 0
deque = 0
FIFO queue = 1
LIFO queue = 1
List = 1
deque = 1
FIFO queue = 2
LIFO queue = 0
List = 2
deque = 2
ラストインファーストアウトのLifoQueue
のみが最後に代入された2
を最初に出力してていて、他の3つは、順番通り0
から出力されているのがわかります。
rotate
queue
の場合は、データを入れた最後の値から抽出するには、別のクラスLifoQueue
を使う必要がありますが、deque
を使えば、取り出す際のメソッドを変えるだけで取り出す順番を変えることができます。
また、rotate
を使えば、deque
に入れている値の順番をローテーションすることもできます。
import collections
d = collections.deque()
for i in range(3):
d.append(i)
print(d)
d.rotate()
print(d)
d.rotate()
print(d)
出力結果
deque([0, 1, 2])
deque([2, 0, 1])
deque([1, 2, 0])
8行目のd
の出力では0
から順番になっていますが、9行目、11行目のrotate
でd
の順番がローテーションされているのがわかります。
extend
extend
を使って値を追加することもできます。
print(d)
d.extend('a')
print(d)
d.extendleft('l')
print(d)
出力結果
deque([0, 1, 2])
deque([0, 1, 2, 'a'])
deque(['l', 0, 1, 2, 'a'])
便宜上8行目からのコードのみ記述していますが、8行目の出力はdeque
に入れた値の順番どおりに出力されています。
9行目のextend('a')
でa
を追加しているので、10行目の出力で、値の最後にa
が追加されているのがわかります。
11行目はextendleft('l')
を使って、左(つまり先頭)にl
を追加しているので、12行目の出力で、l
が追加されているのがわかります。
clear
リストのメソッドで使えるclear
を使えば、deque
に代入した値を一括消去することもできます。
print(d)
d.clear()
print(d)
出力結果
deque([0, 1, 2])
deque([])
8行目の出力は、deque
に代入された値が入っていますが、9行目でclear
を使って、値を削除しているので、10行目の出力で、deque
の中身が空になっているのがわかるかと思います。
まとめ
入れ物の中に値を入れて、前から取り出したり、後ろから取り出したりできるqueue
は便利ですが、deque
は、メモリを使って順番をローテーションしたり、値を前や後ろに追加したり、すべての値をクリアーしたり、高速な処理が可能なので、さらに便利な使い方ができます。
リストやqueue
を使いつつ、これらを拡張したような使い方ができるdeque
は、憶えておいて損はないでしょう。
それでは明日もGood Python!