Python3の華麗なるリスト

まえがき

Python3のリストはシーケンス型の一つ。変更可能体:ミュータブル。リストには順序がある。リストには大抵のものが入れられる。

Pythonのリストには内包表記という便利な機能が用意されている。リストはスタックとして使うことも、キューとして使うこともできる。早速みていこう。

謝辞

「Pythonチュートリアル」の著者、Pythonの産みの親、Guido van Rossum氏。

翻訳者であり日本野人の会CEOである、鴨澤眞夫氏。

出版に携わった全ての人に感謝したい。

変更履歴

新規作成:2020/03/11

この記事の環境

  • OS: MacOS
  • Python: 3.8.1
  • IDE: Spacemacs
  • モジュール:標準モジュール(collections)

リストの作り方

リストはブラケットを使って作る。後述するlist()関数を使った作り方もある。

作り方:コード

# リストを作る
empty_list = []
num_list = [1, 33, 233, 567, 2093, 88, 345, 100]
str_list = ["春", "夏", "秋", "冬"]
list_in_list = [["A", "B", "C"],[111, 222, 333]]
list_in_list = [num_list, str_list]

作り方:実行結果

呼び出し方:コード

 リストから呼び出す
num_list[0]
num_list[3]
num_list[-1]
num_list[0:3]
num_list[:3]
num_list[0:]
num_list[:]
num_list[::2]
list_in_list[0]
list_in_list[0][2]

呼び出し方:実行結果

リストの操作

リストの内容を書き換えたり、付け足したりリストどうしを足し合わせたりできる。

操作:コード

num_list = [1, 33, 233, 567, 2093, 88, 345, 100]
# 書き換える
num_list[3] = 333
num_list[2:4] = [12, 13, 14]
num_list[2:4] = []
num_list[:] = []


num_list2 = [1, 33, 233, 567, 2093, 88, 345, 100]

# 足し合わせる1
new_list = num_list + num_list2
# 足し合わせる2
num_list += num_list2

操作:実行結果

リストのメソッド

Python3のメソッドは全部で11個ある。シーケンス型共通のメソッドも当然使える。

メソッド:コード

num_list = [1, 33, 233, 567, 2093]
# 共通メソッド
len(num_list)
type(num_list)
list("アイウエオ")
num_lists.remove(1)
del num_list(1)
numbers = "1,2,3,4,5,6,7,8"
numbers.split(',')

# リストメソッド
a_list = [1, 2, 3]
b_list = [4, 5, 6]
# リストを合体させる
a_list.extend(b_list)

m_list = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
m_list.index(3)
m_list.index(3, 3)
m_list.count(2)

# 後ろに付け足す
m_list.append(198)
# 指定したところに入れる
m_list.insert(3, 99)
# 後ろから取り出す(削除)
m_list.pop()
# 指定したところを取り出す(削除)
m_list.pop(0)
# ソートする
m_list.sort()
# 逆にソート1
m_list.sort(reverse=True)
# 逆にソート2
m_list.reverse()
# 丸々こぴー
m_list.copy()
# 中身をクリア
m_list.clear()

メソッド:実行結果

リストの内包表記

Pythonには内包表記という便利な機能がある。繰り返し処理などを1行でかける優れものである。あまり多くの入れ子だと逆に1行では分かりにくくなるので注意が必要。そもそも入れ子自体、多いというのは別の問題としてあるが。

内包表記:コード

# リストを作りたい
base_list = [1 ,2 ,3, 4, 5, 6, 7]
ex_list = [8, 9, 10, 11, 12]

list_1 = []
for i in base_list:
    if i % 2 == 0:
        list_1.append(i)

# これを内包表記によって行う
list1 = [i for i in base_list if i % 2 == 0]

# for文が2重の場合は
list_2 = []
for i in base_list:
    for j in ex_list:
        list_2.append(i * j)

# これを内包表記によって行う
list2 = [i * j for i in base_list for j in ex_list]

ラムダよりも内包表記が良い?

どちらも1行で書けるけどどっちがいいかやってみた。

# 2乗数のリストを作る
# ラムダで書く場合
lam_list = list(map(lambda x: x**2, range(10)))

# 内包表記で書く場合
naihou_list = [x**2 for x in range(10)]

短くなるだけで無く、メソッドも少ないし、初めに何が得られるのかが一眼でわかるし、いい事しかない。ついでに使うメモリも少ない(と聞いた)。

リストの中のリストを内包表記で作るとこうなる

# リストの中にあるリスト
list_in_list =[
	[1, 2, 3, 4],
	[5, 6, 7, 8],
	[9, 10, 11 ,12],
	]

# 入れ替える
# リスト内包の先頭の式にはあらゆる式が使える。
[[row[i] for row in matrix] for i in range(4)]

# これは以下と同じ
irekae_list_1 = []
for i in range(4):
    irekae_list_1.append([row[i] for row in matrix)

# さらにこれは以下と同じ
irekae_list = []
for i in range(4):
    irekae_list_row = []
    for row in matrix:
        irekae_list_row.append(row[i])
    irekae_list.append(irekae_list_row)

# 複雑なフローにはzip()関数を使った方が良い
list(zip(*list_in_list))

リストでスタック

スタックとは山積みにするようなイメージのもの。後入れ先出し:las-in, first-outというやつだ。

s_list = []
stack_l = [s.append(i) for i in range(20)]

for i in stack_l:
    stack_l.pop(i)
    print(stack_l)

リストでキュー

キューは入れた順番に取り出すもの。先入先出し:first-in, first-outである。これはinsert()やpop()によってできるが、これは遅い。なぜなら後ろから出すのと違ってpop()で取り出そうとインデックスを指定してやると、取り出したときに残りの全ての要素が左に移動することになるので、取り出すたびに全体が動くとその分時間がかかる。なので「deque()」を使う。

from collections import deque
que_list = deque(["Apple", "Banana", "mango"])
que_list.append("Orange")
que_list.append("Peach")

print(que_list.popleft())
print(que_list.popleft())
print(que_list)

むすび

リストなどのコンテナを作ることを「梱包する:パッキングする」というらしい。次回に取り上げるタプルも同様にパッキングができるし、その逆のアンパッキングもある今回は取り上げなかったが、やり方は同じなのでタプル編でアンパッキングについて覚えよう。でわまた。

コメントする