Python基礎講座 #8 リスト (List)

読了 8分

今回の講座では、Pythonにおいて非常に重要なデータ構造の一つであるリストについて勉強していきましょう。

リストはPythonオブジェクトの集合です。別の言い方をすれば、いろいろな種類のデータを一箇所に保存して参照できるデータ構造です。

リストとは?

リストは重要なdata structureの一つです。 リストはオブジェクトのコレクション(集合)です。 リストはシーケンス型です。 リストはiteratorオブジェクトです。 リストを定義する方法を見ていきましょう。リストはブラケットの中にカンマを区切り文字として使って、いろいろなデータを定義することができます。まず空のリストを定義してみましょう。空のリストを定義する方法には、空のブラケットで定義する方法と、list()コンストラクタを使う方法があります。

まず空のブラケットでリストを定義してみましょう。

>>> []
[]

今度はリストコンストラクタを使ってみましょう。

>>> list()
[]

実際にプログラムを作っていくと、空のリストを定義しなければならないケースが多いので、しっかり覚えておいてください。上の二つの方法のうちどちらを使っても構いませんが、多くのPythonプログラマーは速度がより速いという理由で、空のブラケットで定義する方法を好んでいます。

実際にパフォーマンスを比較してみましょう。

# このコードはipythonやnotebookで実行してください。
In [1]: %timeit []
21.2 ns ± 0.419 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [2]: %timeit list()
52.9 ns ± 0.601 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

明らかに空のブラケットを使う方が速いことが分かります。しかし、何秒でも何ミリ秒でもなく、数十ナノ秒の差なので、どちらを使っても構わないと思います。

今度は1から5までの数字を使って、簡単なリストを定義した後、出力してみましょう。

>>> numbers = [1, 2, 3, 4, 5]
>>> numbers
[1, 2, 3, 4, 5]

一つの変数の中に1から5までのintデータが保存されているのが分かります。type関数を使って、データの型を確認してみましょう。

>>> type(numbers)
<class 'list'>

データの型がリストであることを確認しました。今度はリストの基本機能とリストクラスが提供するクラスメソッドを使ってみましょう。

Pythonが基本的に提供する組み込み関数であるlen関数を使うと、リストのアイテムが何個あるか、つまりリストの長さを確認できます。 len関数を使って、上で定義したリストの長さを確認してみましょう。

>>> len(numbers)
5

リストが5個のアイテムを持っていることを確認しました。

Pythonはリストのアイテムを順番に並べ替えできるよう、sortedという組み込み関数を提供しています。

>>> # 5個の数字を順序なしでリストの中に定義します。
>>> numbers = [3, 2, 1, 5, 4]
>>> # 定義したリストをsorted関数を使って並べ替えてみましょう。
>>> sorted(numbers)
[1, 2, 3, 4, 5]

ここで必ず覚えておいてほしいポイントがあります。sorted関数を使うと、オリジナルリストは並べ替えられず、並べ替えられた新しいリストが返されるということを覚えておいてください。

オリジナルリストの値が変わったか確認してみましょう。

>>> numbers
[3, 2, 1, 5, 4]

ご覧の通り、オリジナルリストは変更されていません。並べ替えられたリストを戻り値として受け取るのが目的ではなく、オリジナルリストの値を変更したい時は、sortというクラスメソッドを使わなければなりません。ただし、逆にsortメソッドを使うと、オリジナルリストは並べ替えられますが、何の値も返されないことを覚えておいてください。

sortメソッドを使ってオリジナルリストを並べ替えてみましょう。

>>> numbers.sort()
>>> numbers
[1, 2, 3, 4, 5]

オリジナルリストが並べ替えられたことを確認しました。

組み込み関数であるmaxとmin関数を使って、リストのアイテムの最大値と最小値を確認することもできます。

max関数を使って最大値を出力してみましょう。

>>> max(numbers)
5

今度はmin関数を使って最小値を出力してみましょう。

>>> min(numbers)
1

sum関数を使ってすべてのアイテムの合計を求めることもできます。

>>> sum(numbers)
15

今度はリストの基本機能について見ていきましょう。リストはPythonが提供する6つのシーケンス型のうちの一つです。Pythonのシーケンス型のもう一つは、前回の講座で勉強した文字列型です。シーケンスの意味を英語の辞書で調べると、配列、順序、手順、連続的な出来事などと説明されています。つまりシーケンス型とは、データを配列として、または順番に管理できる型のことを言います。シーケンス型は順序のあるデータなので、数字によるインデックスを通じて内部のアイテムにアクセスできます。 インデックスを使って文字列のアイテムにアクセスできるのと同じように、リストのアイテムもインデックスを使ってアクセスすることができます。また、スライシングをすることもできます。Pythonはゼロベースインデックスを使うため、左端のアイテムのインデックスが0で、右に移動するごとにインデックスが1ずつ増えるということを前回の講座で学びました。リバースインデックスを使って、最後のアイテムからアクセスすることもできます。

Pythonシーケンス型

str unicode list tuple buffer range もう一度1から5までの数字をリストの中に定義してみましょう。

>>> numbers = [1, 2, 3, 4, 5]

リストの最初のアイテムである1を出力してみましょう。

>>> numbers[0]
1

最後のアイテムである5を出力してみましょう。

>>> numbers[4]
5

今度はリバースインデックスを使って、最後のアイテムである5を出力してみましょう。

>>> numbers[-1]
5

スライシングを使って、最初の3個のアイテムを出力してみましょう。

>>> numbers[0:3]
[1, 2, 3]

スタートインデックスが0の場合は、次のように省略しても構いません。

>>> numbers[:3]
[1, 2, 3]

今度は最後の3個のアイテムを出力してみましょう。

>>> numbers[-3:]
[3, 4, 5]

今度はリストの機能の中で最も重要な機能であるiteratingについて確認してみましょう。

Pythonオブジェクトの中には、for loopで使えるiteratorオブジェクトがあります。リストもiteratorオブジェクトであり、for loopを使ってそれぞれのアイテムにアクセスできます。オブジェクトがiteratorオブジェクトかどうかは、iter関数を使って確認できます。

>>> iter(numbers)
<list_iterator object at 0x7fee58134a30>

リストがiteratorオブジェクトであることを確認しました。

今度は文字列オブジェクトがiteratorオブジェクトかどうか確認してみましょう。

>>> iter('string')
<str_iterator object at 0x7fee58134790>

今度はfor loopを使って、リストの中のそれぞれのアイテムを出力してみましょう。

>>> for i in numbers:
...     print(i)
...
1
2
3
4
5

文字列オブジェクトもiteratorオブジェクトなので、for loopを使うことができます。

>>> for i in 'string':
...     print(i)
...
s
t
r
i
n
g

次はconcatenating機能です。この機能は、プラス (+) 演算子を使って二つのリストを一つに結合することを言います。

>>> list_1 = [1, 2, 3]
>>> list_2 = [4, 5]
>>> new_list = list_1 + list_2
>>> new_list
[1, 2, 3, 4, 5]

アスタリスク (asterisk) 演算子を使って、リストのアイテムを複製することもできます。

>>> new_list * 3
[1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5]

それぞれのアイテムが3個ずつ複製されたことが分かります。

リストの基本機能

Indexing Slicing Iterating Concatenating Multiplying リストと一緒に使える組み込み関数

len sorted max min sum 今度はクラスメソッドを使ってみましょう。

まずリストクラスにはどんなメソッドが定義されているか、help関数を使って確認してみましょう。

>>> help(list)
Help on class list in module builtins:

class list(object)
|  list(iterable=(), /)
|
|  Built-in mutable sequence.
|
|  If no argument is given, the constructor creates a new empty list.
|  The argument must be an iterable if specified.
|
|  Methods defined here:
|
|  __add__(self, value, /)
|      Return self+value.
|
|  __contains__(self, key, /)
|      Return key in self.
|
|  __delitem__(self, key, /)
|      Delete self[key].
|
|  __eq__(self, value, /)
|      Return self==value.
|
:

まずリストにアイテムを追加するappendメソッドを使ってみましょう。

>>> numbers = [1, 2, 3, 4, 5]
>>> numbers.append(6)
>>> numbers
[1, 2, 3, 4, 5, 6]

新しいアイテム6が最後のアイテムとして追加されたことが分かります。

今度はリストとリストを連結するextendメソッドを使ってみましょう。

>>> numbers.extend([7, 8])
>>> numbers
[1, 2, 3, 4, 5, 6, 7, 8]

既存のリストと新しいリストが一つのリストになりました。

プラス (+) 演算子を使って二つのリストを結合することもできます。

💡 今日のヒント

二つのリストを結合するためには、extendまたは+演算子を使ってください。決してappendメソッドを使ってはいけません!

ここで注意する点があるのですが、多くの初心者の方が二つのリストを結合するためにappendメソッドを使ってしまいます。appendメソッドを使うとどんな結果になるか、まず確認してみましょう。

>>> numbers.append([9, 10])
>>> numbers
[1, 2, 3, 4, 5, 6, 7, 8, [9, 10]]

ご覧の通り、appendメソッドを使うと、二つのリストが結合されるのではなく、二つ目のリストが一つ目のリストの最後のアイテムとして追加されるので、注意してください。

任意の位置に新しいアイテムを追加したい時は、insertメソッドを使えば大丈夫です。insertメソッドに渡される一つ目の引数は、新しいアイテムが位置することになるインデックスで、二つ目の引数はアイテムの値です。

>>> numbers = [1, 2, 4, 5]
>>> numbers.insert(2, 3)
>>> numbers
[1, 2, 3, 4, 5]

今度はremoveメソッドを使ってアイテムを削除してみましょう。removeメソッドを使う時は、削除したいアイテムのインデックスではなく、アイテムの値を使わなければなりません。

X