K - 1.10.リスト Editorial /

Time Limit: 0 msec / Memory Limit: 0 KB

前のページ | 次のページ

キーポイント

  • リスト は様々なデータの列を扱うことができる
  • [要素0, 要素1, 要素2, ...] でリストを作ることができる
  • [0] * NN 個の 0 からなるリストを作ることができる
  • a[i] でリスト ai 番目の要素を取得できる
  • list(map(int, input().split()))1 行の入力から整数のリストを作ることができる
  • リストと for 文を組み合わせると、大量のデータを扱うプログラムを簡単に書ける

リスト

リスト(配列、list 型) はデータの列を扱うことができる非常に重要な機能です。例えば、以下のようなコードを書くことができます。

# リスト [3, 1, 4, 1, 5] を作り, a に代入する
a = [3, 1, 4, 1, 5]

# a の 0 番目の要素である 3 を出力
print(a[0])

# a の 1 番目の要素である 1 を出力
print(a[1])

# a の 2 番目の要素 (4) を 7 に変更
a[2] = 7

# a の要素を順に出力
for x in a:
    print(x)
出力
3
1
3
1
7
1
5

この章では、リストの使い方について説明します。

リストを作る

  • [] で空のリストを作ることができます。
  • [要素0, 要素1, 要素2, ...] でリストを作ることができます。
  • list( for文に入れられるもの ) でリストを作ることができます。
    • 例えば、for i in range(5): と書くと i0, 1, 2, 3, 4 が順番に入るので、list(range(5)) と書くとリスト [0, 1, 2, 3, 4] を作ることができます。
  • 2 章で紹介する リスト内包表記 を使ってもリストを作ることができます。
# 空のリストを作り、a に代入する
a = []

# リスト [3, 1, 4, 1, 5] を作り、a に代入する
a = [3, 1, 4, 1, 5]

# いろいろな型を持つデータを 1 つのリストに入れることができる
a = ["Hello", "AtCoder", 123, 4.5, []]

# リスト [0, 1, 2, 3, 4] を作る
a = list(range(5))

リストの長さ

  • リスト a に対し、len(a)a の長さ(要素数)を取得できます。

リストの i 番目の要素

  • リスト a と整数 i に対し、a[i]ai 番目の要素を取得できます。
    • この i のこと(リストの何番目の要素かを表す番号)を 添字(そえじ) と言います。
    • リストの添字は 0 から始まることに注意しましょう。 先頭の要素は a[0] で、末尾の要素は a[len(a)-1] で取得することができます。
  • a[i] = xai 番目の要素を x に変更できます。
# リスト [3, 1, 4, 1, 5] を作り、a に代入する
a = [3, 1, 4, 1, 5]

# a の長さ 5 を出力する
print(len(a))

# a の 2 番目の要素 (4) を 7 に変更する
a[2] = 7

# range(len(a)) と書けば a の添字 (0, 1, 2, 3, 4) を順に列挙できる
for i in range(len(a)):
    # a[i] で a の i 番目の要素を取得する
    print(i, ":", a[i])
出力
5
0 : 3
1 : 1
2 : 7
3 : 1
4 : 5

for 文でリストの要素を列挙する

  • リスト a に対し、for x in a:a の要素を順に x に代入して繰り返し処理を行うことができます。
a = [3, 1, 4, 1, 5]

# a の要素を順に x に代入し、繰り返し処理を行う
for x in a:
    # 5 回実行される
    print(x)
出力
3
1
4
1
5

入力からリストを作る

  • 文字列 s に対し、s.split()s を空白で区切って文字列のリストを作ることができます。
  • 文字列のリスト a に対し、list(map(int, a))a の各要素を整数に変換したリストを作ることができます。
  • list(map(int, input().split())) で、入力から 1 行読み取り、空白で区切って整数のリストを作ることができます。
# 入力から 1 行読み取り、空白で区切って整数のリストを作る
a = list(map(int, input().split()))

print(a)
入力
886 551 37 424 531
出力
[886, 551, 37, 424, 531]

リストを出力する

  • リスト a に対し、print(*a)a の要素を空白区切りで出力できます。
a = [9, 9, 7, 3]

# a の要素を空白区切りで出力する
print(*a)

# a の要素を改行区切りで出力する
for x in a:
    print(x)
出力
9 9 7 3
9
9
7
3

リストの使い所

リストと for 文を組み合わせると、以下のように大量のデータを扱うプログラムを書くことができます。

例題

N 人の生徒が数学のテストと英語のテストを受けました。テストはそれぞれ 100 点満点で、生徒 i\ (1 \le i \le N) の数学の点数は M_i 、英語の点数は E_i でした。それぞれの生徒について、数学のテストと英語のテストの合計点を求めてください。

制約

  • 入力される値はすべて整数
  • 1 \le N \le 1000
  • 0 \le M_i \le 100\ (1 \le i \le N)
  • 0 \le E_i \le 100\ (1 \le i \le N)

入力

入力は以下の形式で与えられる。

N
M_1 M_2 \cdots M_N
E_1 E_2 \cdots E_N

出力

S_i\ (1 \le i \le N) を生徒 i の数学のテストと英語のテストの合計点とする。
以下の形式で出力せよ。

S_1
S_2
\vdots
S_N

入力例

3
20 100 30
100 5 40

出力例

120
105
70

解答例

N \le 3 のような N が非常に小さいという制約がついていれば、N で場合分けすることによってリストを使わずに解くことも可能です。しかし、N が大きくなるとこれは非現実的になってしまいます。

リストと for 文を用いれば、N の大きさに関わらず簡潔に処理を書くことができます。

# 生徒の人数 N を入力
N = int(input())

# 数学の点数 M を入力
M = list(map(int, input().split()))

# 英語の点数 E を入力
E = list(map(int, input().split()))

# それぞれの生徒について処理する
for i in range(N):
    # 生徒 i の合計点 M[i] + E[i] を出力する
    print(M[i] + E[i])

リストのさらなる機能

負の添字

  • リスト a負の整数 i に対し、a[i]a後ろから -i-1 番目の要素を取得することができます。末尾の要素は a[-1] で、先頭の要素は a[-len(a)] で取得することができます。

範囲外アクセス

  • 存在しない要素を取得しようとすると、RE が発生します。
a = [3, 1, 4, 1, 5]

# 負の添字で後ろから順番に要素を取得
print(a[-1])
print(a[-2])
print(a[-3])

# a の 5 番目の要素は存在しないので、実行時エラーが発生する
print(a[5])
出力
5
1
4
エラー出力
Traceback (most recent call last):
  File "/judge/Main.py", line 8, in <module>
    print(a[5])
          ^^^^
IndexError: list index out of range
終了コード
256

エラー出力を見ると、8 行目の a[5] の部分で、IndexError: list index out of range (リストの添字の範囲外) というエラーが起きていることがわかります。

リストをつなげる

  • リスト a とリスト b に対し、a + bab をつなげたリストを作ることができます。
  • リスト a と整数 n に対し、a * nan 回繰り返したリストを作ることができます。
# リスト [1, 6] とリスト [1, 8] をつなげて [1, 6, 1, 8] を作り、a に代入する
a = [1, 6] + [1, 8]

# [1, 6, 1, 8] に [0, 3, 3] をつなげて [1, 6, 1, 8, 0, 3, 3] とする
a += [0, 3, 3]

# リスト [0, 1, 2] を 3 回繰り返したリスト [0, 1, 2, 0, 1, 2, 0, 1, 2] を作り、a に代入する
a = [0, 1, 2] * 3

リストの末尾に要素を追加・削除する

  • リスト a と値 x に対し、a.append(x)a の末尾に要素 x を追加できます。
  • リスト a に対し、a.pop()a の末尾の要素を取得しながら削除できます。
# 空のリストを作り、a に代入する
a = []

# a の末尾に 1 を追加する。a は [1] になる。
a.append(1)
# a の末尾に 2 を追加する。a は [1, 2] になる。
a.append(2)
# a の末尾に 3 を追加する。a は [1, 2, 3] になる。
a.append(3)

# a の末尾の要素 3 を出力し、削除する。a は [1, 2] になる。
print(a.pop())
# a の末尾の要素 2 を出力し、削除する。a は [1] になる。
print(a.pop())
# a の末尾の要素 1 を出力し、削除する。a は [] になる。
print(a.pop())
出力
3
2
1

リストの好きな位置に要素を追加・削除する

  • リスト a と整数 i と値 x に対し、a.insert(i, x)ai 番目の位置 (a[i-1]a[i] の間) に x を挿入することができます。
  • リスト a と整数 i に対し、a.pop(i)ai 番目の要素を取得しながら削除することができます。

リストの途中への挿入・削除は、それ以降の要素をずらす必要があるため、末尾への挿入・削除と比べて時間がかかります。

リストの中に x があるか調べる

  • リスト a と値 x に対し、x in axa の中に 1 個以上存在するかを判定することができます。
    • not (x in a)x not in a と書くこともできます。
  • リスト a と値 x に対し、a.count(x)xa の中に何個存在するかを取得することができます。
  • リスト a と値 x に対し、a.index(x)a の中に x が出現する最初の位置を取得することができます。
# x が 1, 2, 3 のいずれかであるかを判定する
x = 2
print(x in [1, 2, 3])

a = [3, 1, 4, 1, 5]

# a の中に存在する 1 の数 (2 個) を数える
print(a.count(1))

# a の中に存在する最初の 1 の位置 (a[1]) を調べる
print(a.index(1))
出力
True
2
1

リストをソートする

  • リスト a に対し、a.sort()a の要素を昇順に並べ替えることができます。

リストを反転する

  • リスト a に対し、a.reverse()a の要素を逆順に並べ替えることができます。
a = [3, 1, 4, 1, 5]

# a を昇順に並び替える。a は [1, 1, 3, 4, 5] になる。
a.sort()
print(a)

# a を反転する。a は [5, 4, 3, 1, 1] になる。
a.reverse()
print(a)
出力
[1, 1, 3, 4, 5]
[5, 4, 3, 1, 1]

リストを複製する

リスト a に対し b = a とすると、リストは複製されず、a の指すリストと b の指すリストは同一のものになります。

# リスト [3, 1, 4, 1, 5] を作り、a に代入する
a = [3, 1, 4, 1, 5]

# a が指しているリストを b に代入する
b = a

# a の指すリストと b の指すリストは同一のため、a を変更すると b も変わっている
a[2] = 7
print(b)
# b を変更すると a も変わっている
b.append(9)
print(a)
出力
[3, 1, 7, 1, 5]
[3, 1, 7, 1, 5, 9]

これを回避するには、b = a.copy() と書いて、リストを複製する必要があります。

# リスト [3, 1, 4, 1, 5] を作り、a に代入する
a = [3, 1, 4, 1, 5]

# a が指しているリストを複製して b に代入する
b = a.copy()

# a の指すリストと b の指すリストは別物のため、a を変更しても b は変わらない
a[2] = 7
print(b)
出力
[3, 1, 4, 1, 5]

リストの一部分を複製する(スライス)

  • リスト a と整数 l,r\ (0 ≤ l ≤ r ≤ \text{len}(a)) に対し、a[l:r]a[l] から a[r-1] までの r-l 要素からなるリストを作ることができます。
a = [3, 1, 4, 1, 5]

# a[1] から a[3] までの 3 要素からなるリストを作る
print(a[1:4])

# a[0] から a[4] までの 5 要素からなるリストを作る
print(a[0:5])
出力
[1, 4, 1]
[3, 1, 4, 1, 5]
  • リスト a と正整数 l,r\ (0 ≤ l ≤ r ≤ \text{len}(a))正整数 \mathit{step} に対し、a[l:r:step]a[l:r] の範囲から \mathit{step} 要素ごとに取り出したリストを作ることができます。
    • より正確には、d = \bigl\lceil\frac{r-l}{\mathit{step}}\bigr\rceil とすると、長さ d のリスト [a[l+step*0], a[l+step*1], ..., a[l+step*(d-1)]] が作られます。
    • l を省略すると l = 0 扱いに、r を省略すると r = \text{len}(a) 扱いに、\mathit{step} を省略すると \mathit{step} = 1 扱いになります。特に a[:] と書くと、リスト a を複製することができます。
a = [3, 1, 4, 1, 5, 9]

# a[0:6] を作る (リストを複製する)
print(a[:])

# a[0:6] から 2 要素ごとに取り出したリストを作る
print(a[::2])

# a[1:6] から 2 要素ごとに取り出したリストを作る
print(a[1::2])

# a[1:5] から 3 要素ごとに取り出したリストを作る
print(a[1:5:3])
出力
[3, 1, 4, 1, 5, 9]
[3, 4, 5]
[1, 1, 9]
[1, 5]

リストを比較する

  • リスト a, b に対し、a == b / a != b でリストの全要素が一致しているかを判定することができます。
  • リスト a, b に対し、a < b / a <= b / a > b / a >= bab を辞書式順序で比較できます。

公式ドキュメント

より詳しい情報を知りたい場合は、以下の公式ドキュメントを参照してください。

https://docs.python.org/ja/3/library/stdtypes.html#list

問題

リンク先の問題を解いてください。