こんな人にオススメ
python
のlist
ってなんなの?
どういうことが出来てどういう時に便利なの?
ということで、今回はpythonにおけるlist
の超基礎について解説する。list
のような書き方はよく使うと思われるので是非とも本記事で基礎を知ってもらえればと思う。
以前公開した、pythonを独学で学ぶために知っておきたいマインドについては以下参照。
-
-
【python&独学】独学である程度pythonを習得するマインド
続きを見る
python環境は以下。
- Python 3.9.2
list
とは
pythonにおけるlist
とは、pythonに標準搭載されている、複数の要素を一括で管理できる箱(配列)のようなものだ。中身は変更可能で、追加や削除などが行える。
list
のイメージ
list
のイメージは以下のような感じ。[]
の中に要素として数値や文字列を入れることで使用することができる。
lst = [1, True, 'aaa'] print(lst) # [1, True, 'aaa']
list
の活用方法
list
っていつ、どういう場面で使用するのかだが、例えば複数回同じテストが行われる状況を考えていただきたい。
この時、ノー勉でテストした時の点数が30点、1回勉強した時の点数が60点、2回目の勉強の時の点数が70点、3回目の点数が80点、4回目の点数が90点だったとしよう。
これらの点数を変数を使用して表すと例えば以下のようになる。
test0 = 30 test1 = 60 test2 = 70 test3 = 80 test4 = 90
今回はテストの回数が4回だけだったから上記のようにtest4
のように連番を振ったっが、これがtest100
やtest1000
のように数が増えるとこの方法だと書く量が半端ではなくなる。
上記のことをlist
を使用して書くと以下のように書ける。
test = [30, 60, 70, 80, 90]
かなりスッキリした。ただ、この場合だとどの要素(ここでいう点数)が何回目かがわかりにくい。その場合は辞書型(dict
)を使用する方がいい。
本記事では扱わないが、一応dict
を使用した場合での書き方を以下に示す。
test_dct = {'0': 30, '1': 60, '2': 70, '3': 80, '4': 90}
dict
にすると何回目かがわかりやすい。ただし、dict
は後ほど説明するlist
とは操作の方法が異なるので別途勉強が必要。
list
の作り方
ここからは実際にlist
の作成方法について解説していく。最初は深く考えずにとにかく書いて動かしていくのがいいだろう。
[]
で作る
まずは先ほども出てきた[]
を使用して作成する方法。
test = [30, 60, 70, 80, 90]
要素を取り出したい時は(list名)[(取り出したい要素のインデックス)]
の形式で行う。「インデックス」とは何番目にあるかの番号のこと。
ここで気をつけないといけないのが、先頭のインデックスは0
であるということ。1
にすると一つ後の要素が選ばれるので注意。
test = [30, 60, 70, 80, 90] print(test[0]) # 30 print(test[1]) # 60 print(test[2]) # 70 print(test[3]) # 80 print(test[4]) # 90
list()
で作る
次の作り方はlist()
を使用するというもの。[]
と何が違うのかはややこしくなるので割愛。初めは好きな方を選んで、エラーとか変な挙動を示したら勉強すればいいと思う。
具体的な作り方は以下。
test = list((30, 60, 70, 80, 90)) test = list([30, 60, 70, 80, 90])
list(
の後に[
とするか(
とするかの違いだがどちらでもいい。今回も要素を取り出してみる。
print(test[0]) # 30 print(test[1]) # 60 print(test[2]) # 70 print(test[3]) # 80 print(test[4]) # 90
結果はもちろん同じ。
range
で作る
また違った書き方としてrange
を使う方法がある。range
は一定の法則に従った連番を作成するというもので、そのrange
をlist
に変換する。
ただ、連番を作成するというものなので、今回のtest0
の30
を表現するのは難しい。以下の例ではtest1
の60
から作成している。
serial = list(range(60, 100, 10)) print(serial) # [60, 70, 80, 90] print(serial[0]) # 60 print(serial[2]) # 80
range(60, 100, 10)
は60
から100
までを10
刻みで、ということだがpythonの場合は100
は数えない。意味合いとしては<100
のイメージ。10
刻みなので<100
の条件に合う最後の数値は90
となる。
[~]*(数字)
で繰り返し作成
同じ要素の繰り返しを作成したい場合は、繰り返したい要素に繰り返したい回数をかければいい。
lst = [30, 40, 50] * 3 print(lst) # [30, 40, 50, 30, 40, 50, 30, 40, 50]
list
に要素を追加
list
の作成方法は述べた。では、既存のlist
に要素を追加したい場合はどうすればいいのか。ここでは要素の追加について解説する。
.append
で後ろに追加
まずは.append
を使用する方法。.append
を使用するとlistの最後尾に要素を追加することができる。以下では最後尾に100
を追加した。
test = [30, 60, 70, 80, 90] test.append(100) print(test) # [30, 60, 70, 80, 90, 100]
ただし、追加する要素は1つのみで、2つ以上追加しようとするとエラーとなる。
test = [30, 60, 70, 80, 90] test.append(95, 100) # test.append(95, 100) # TypeError: list.append() takes exactly one argument (2 given)
2つ以上がダメなら1つにすればいいのではということで[95, 100]
とすると、エラーは出ないがその代わりにネスト(入れ子)状態になってしまう。
test = [30, 60, 70, 80, 90] test.append([95, 100]) print(test) # [30, 60, 70, 80, 90, [95, 100]]
なお、.append
は要素を追加するだけなので、戻り値(結果こうなりました的なもの)がなく、print
してもNone
が返される。
test = [30, 60, 70, 80, 90] print(test.append(100)) # None
[~]+[...]
で追加
では複数個の要素を同時にくっつけたい時はどうすればいいのか。それはlist
同士を足し算すれば解決する。例えば以下の例だと、95点と100点を1つのlist
に置いてから足し算している。
test = [30, 60, 70, 80, 90] add = [95, 100] test_new = test + add print(test_new) # [30, 60, 70, 80, 90, 95, 100]
この場合もどんどん後ろに追加される。add
の要素が1つの時も3つ以上も同様に追加可能。
.insert
で任意の場所に追加
.insertを使用することで、任意の位置に要素を追加することができる。書き方は以下。
.insert((要素を追加したいインデックス), (追加したい要素))
以下ではインデックスとして1
を選択し(30
と60
の間)、追加したい要素は45
とした。
test = [30, 60, 70, 80, 90] test.insert(1, 45) print(test) # [30, 45, 60, 70, 80, 90]
インデックスは30
の左が0
番目で、30
と60
の間が1
番目で...というように割り振られている。したがって、この場合だとインデックスに5
を指定することで最後尾に要素を追加することができる。
test = [30, 60, 70, 80, 90] test.insert(5, 100) print(test) # [30, 60, 70, 80, 90, 100]
この場合もappend
と同じように同時に複数個の要素を挿入することはできない。
test = [30, 60, 70, 80, 90] test.insert(1, 45, 55) # test.insert(1, 45, 55) # TypeError: insert expected 2 arguments, got 3
list
にして挿入すればエラーを回避できるが、append
の時と同様、ネストされた状態になる。
test = [30, 60, 70, 80, 90] test.insert(1, [45, 55]) print(test) # [30, [45, 55], 60, 70, 80, 90]
なお、.insert
も.append
と同じように、print
してもNone
が返されれるだけ。
test = [30, 60, 70, 80, 90] print(test.insert(1, 45)) # None
list
から要素を削除
要素の追加を知ったところで、次は要素を削除する方法について解説する。要素の削除の仕方はたくさんあるが、ここでは簡単なものだけに絞って解説する。
del
で削除
まずはdel
を用いた要素の削除方法。シンプルにdel
だけすると、要素だけではなく変数そのものが削除される。すなわち定義されていないことになる。
test = [30, 60, 70, 80, 90] del test print(test) # print(test) # NameError: name 'test' is not defined
だから、del
で削除する際にはどの要素を削除するのかを指定する必要がある。以下では1番目の60
を削除している。
test = [30, 60, 70, 80, 90] del test[1] print(test) # [30, 70, 80, 90]
法則にしたがって要素を削除したい場合は、:
を使ってスライスで削除する。イメージはrange
の時と同じ。以下では1番目の30
から3番目の80
までを削除した(1:4
の4
は<4
の意味)。
test = [30, 60, 70, 80, 90] del test[1:4] print(test) # [30, 90]
list
の定義は削除せずに全要素を削除したい場合は、スライスを[:]
とする。
test = [30, 60, 70, 80, 90] del test[:] print(test) # []
スライスで削除
del
に似ている方法として単にスライスを使用する方法がある。使い方はシンプルで、削除したい要素を空のlist
、[]
に置き換えるだけ。
例えば、以下の例だとスライスを[1:2]
にすることでインデックスが1
以上2
未満の要素を消している。
test = [30, 60, 70, 80, 90] test[1:2] = [] print(test) # [30, 70, 80, 90]
もちろん複数要素を一括で削除することも可能。
test = [30, 60, 70, 80, 90] test[1:4] = [] print(test) # [30, 90]
あるインデックス以降の要素を全て削除したい場合は[1:]
のようにすればいい。以前の場合は例えば[:4]
のようにする。スライス寄りの話だったのでスライスでの削除の項目で紹介したが、もちろんdel
でも使用できる。
test = [30, 60, 70, 80, 90] test[1:] = [] print(test) # [30]
単に数値だけ指定した場合は、要素が空のlist
に置き換わる。
test = [30, 60, 70, 80, 90] test[1] = [] print(test) # [30, [], 70, 80, 90]
全要素を削除したい時は[:]
とする。
test = [30, 60, 70, 80, 90] test[:] = [] print(test) # []
remove
で削除
最後にremove
を使った削除方法について解説する。今まではインデックスを指定して削除するという方法だった。しかしremove
は要素を指定して削除するというもの。
test = [30, 60, 70, 80, 90] test.remove(60) print(test) # [30, 70, 80, 90]
ただし、気をつけないといけないのが、最初に見つかった要素を削除するという点。以下では30
と60
の間に90
を追加してremove
してみた。
するとその90
だけが削除され、もともと最後尾にあった90
は残ったままであることが確認できる。
test = [30, 90, 60, 70, 80, 90] test.remove(90) print(test) # [30, 60, 70, 80, 90]
また、存在しない要素を指定するとエラーになる。
test = [30, 60, 70, 80, 90] test.remove(100) print(test) # test.remove(100) # ValueError: list.remove(x): x not in list
.remove
も.append
, .insert
と同じように戻り値がないのでprint
してもNone
が返される。
test = [30, 60, 70, 80, 90] print(test.remove(60)) # None
list
の結合(マージ)
list
の作り方、要素の追加と削除ができてlist
を作成したとする。ここで、複数のlist
を一つにした方がいいと考えた場合はどうすればいいか。list
同士を結合(マージ)すればいい。
シンプルに+
まずはシンプルに足し算する方法。+
の後のlist
が後ろに追加される。
test1 = [30, 60] test2 = [70, 80, 90] test = test1 + test2 print(test) # [30, 60, 70, 80, 90]
.extend
で追加
.extend
を使用することでlist
の後ろにlist
を追加することができる。ただし、.append
などと同じように、=
を使わない。
test1 = [30, 60] test2 = [70, 80, 90] test1.extend(test2) print(test1) # [30, 60, 70, 80, 90]
したがって、test =
のように新たな変数として置いたとしてもNone
が返されるだけだ。あくまでも既存のlist
に追加するという形を取っている。
test = test1.extend(test2) print(test) # None
list
のsort
これまではlist
は昇順で書いていたが、もしも順番がバラバラの場合はどうやって昇順にすればいいのか。そんな時は順番を変更すればいい。
.sort
また出てきた.
シリーズ。.sort
でlist
を昇順に並び替える。
test = [60, 70, 90, 80, 30] test.sort() print(test) # [30, 60, 70, 80, 90]
逆に降順にしたい場合は引数としてreverse=True
を選択すればいい。初期状態だとFalse
だ。
test = [60, 70, 90, 80, 30] test.sort(reverse=True) print(test) # [90, 80, 70, 60, 30]
もちろん.sort
をprint
してもNone
。
test = [60, 70, 90, 80, 30] print(test.sort()) # None
sorted
.sort
の場合は既存のlist
を変更するものだったが、既存は残したい場合はsorted
を使用する。
test = [60, 70, 90, 80, 30] sorted_test = sorted(test) print(sorted_test) # [30, 60, 70, 80, 90]
こちらも降順にしたい時はreverse=True
にする。
test = [60, 70, 90, 80, 30] sorted_test = sorted(test, reverse=True) print(sorted_test) # [90, 80, 70, 60, 30]
list
とtuple
最後にlist
に近いtuple
を紹介する。list
が[]
を使用していたのに対し、tuple
は()
を使用する。ただし、ここで気をつけないといけないのは、tuple
を作成するには,
が必ず必要なこと。
以下の例では,
を入れるか入れないかで変数のtype
がどう変わるのかを調べた。
tpl = (30,) num = (30) print(tpl) # (30,) print(type(tpl)) # <class 'tuple'> print(num) # 30 print(type(num)) # <class 'int'>
(30,)
とした変数tpl
ではtuple
として認識されている一方、(30)
としたnum
ではint
として認識されている。この点には注意が必要だ。
list
とtuple
の主な違いは以下の2つ。
- 変更可能か否か
- 速度
変更可能か否か
まず、変更可能かどうかについてだが、list
の場合は以下のようにして要素を変更することができた。
lst = [30, 60, 70, 80, 90] lst[1] = 55 print(lst) # [30, 55, 70, 80, 90]
一方でtuple
の場合はこの方法で要素を変更することができない。一応、要素を変更する方法は存在するが面倒だし実用的ではないのでここでは省く。
tpl = (30, 60, 70, 80, 90) tpl[1] = 55 # tpl[1] = 55 # TypeError: 'tuple' object does not support item assignment
速度
tuple
は要素の変更ができないということもあり、list
よりもコードの実行が早いらしい。しかし、微微たる差であるのでそこまで気にしなくて良い。
使い分け
結局のところlsit
とtuple
の使い分けは以下のようにすればいい。
- 要素の変更を行う:
list
- 要素の変更を行わない:
tuple
まあ、そこまで深く考えなくてもいいだろう。
配列を使い始めてからが本当の始まり
pythonではlist
以外にも多くの配列が存在する。そしてありとあらゆる場面で配列は使われる。その中で配列の考え方がわかっていないとpython
がしんどくなると思われる。
これらの配列の基礎的なものはlist
にあると思うので本記事でlist
への理解を深めていただければ幸いだ。
関連記事
-
-
【python&独学】独学である程度pythonを習得するマインド
続きを見る
-
-
【辞書の結合】dictのマージ
続きを見る
-
-
【辞書&pandas】dict{name: , val: {a: [~], b:[~]}}のpandas化
続きを見る
-
-
【python3.7以降&dictのkeys】ネスト(入れ子)されたdictのkeys一覧をカッコで出力
続きを見る