Pythonでリストを操作する際に、特定の範囲を逆順にしたいことがあるかもしれません。
今回は、その実現方法と、よく使われるreversed()
関数について詳しく解説します。
(自分の備忘録的なものとして残します。同じ初級者が調べものをしている際お役に立てれば幸いです)
リストの一部分を逆順にする関数の作成
例えば、リストの特定の範囲(start
位置からend
位置まで)を逆順に変更したい場合、どのようにコードを書くかを見ていきましょう。
最初に考えた方法(間違いが含まれています)
最初に書いたコードでは、次のような形でreversed()
関数を使用してリストを逆順にしようとしました。
そして、私は、なんでNoneがでるの??と疑問でした。
def f(ls, intStart, intEnd):
for i in reversed(ls):
print(i)
result = f(list7, 0, len(list7)-1)
print(result)
しかし、このコードには一つ問題があります。reversed()
はリストを逆順にして返す関数ですが、f()
関数内でprint(i)
を使って出力しているだけで、リスト自体を変更したり、戻り値を返していません。結果として、f()
を実行した後にNone
が表示されてしまうのです。
出力結果
10
9
8
7
6
5
4
3
2
1
0
None
None
が出力される理由は、f()
関数内でreturn
を使っていないため、関数呼び出し後に自動的にNone
が返されるためです。
確かに言われてみたら納得です。でも初心者なので、最初はわかりませんでした(笑)
正しい方法:リストの一部分を逆順に変更
1. リストを逆順にするだけの場合
リストをそのまま逆順にするには、reversed()
を使うのが簡単です。以下はその例です。
def f(ls, intStart, intEnd):
ls[intStart:intEnd+1] = reversed(ls[intStart:intEnd+1]) # リストの特定部分を逆順に変更
list7 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
f(list7, 0, len(list7)-1) # リスト全体を逆順にする
print(list7) # [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
このようにすることで、リスト全体が逆順に変更され、関数の戻り値は不要です。
2. 新しいリストとして返す場合
もし逆順にしたリストを新たに取得したい場合、return
を使って新しいリストを返す方法もあります。例えば、以下のように書けます。
def f(ls, intStart, intEnd):
# 方法1: リストの一部分を逆順にして、新しいリストを作成
newlist = ls[:intStart] + list(reversed(ls[intStart:intEnd+1])) + ls[intEnd+1:]
# 方法2: reversed() の結果をそのまま返す(イテレータを返す)
newlist = reversed(ls[intStart:intEnd+1]) # ★ イテレータのまま
# 方法3: スライスを使ってリストの一部分を逆順にする
newlist = ls[intStart:intEnd+1][::-1] # スライスで逆順
return newlist
list7 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
result = f(list7, 0, len(list7)-1) # 新しいリストを取得
print(result) # [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
この場合、f()
関数は逆順にしたリストを返し、元のリストは変更されません。
※方法1の詳細
first_part: ls[:intStart] で、intStartより前の部分を取り出します。
middle_part: ls[intStart:intEnd+1] で、逆順にする部分を取り出し、それを list(reversed(...)) で逆順にします。
last_part: ls[intEnd+1:] で、intEndより後ろの部分を取り出します。
reversed()
関数の詳しい解説
reversed()
は、Pythonの組み込み関数で、指定したリストやシーケンス(タプルや文字列など)を逆順にしたイテレータを返します。元のリスト自体は変更されません。
reversed()
の使い方
lst = [1, 2, 3, 4]
reversed_lst = reversed(lst)
# reversed_lstはイテレータなので、リストに変換する必要がある
print(list(reversed_lst)) # [4, 3, 2, 1]
-
reversed()
関数は元のリストを逆順にして返しますが、リストそのものを変更することはありません。リストに変換したい場合は、list()
で囲む必要があります。 -
reversed()
はイテレータを返すため、直接リストとして使用することはできません。list()
やfor
ループで利用します。
reversed()
の挙動について詳しく説明
1. リストそのものを変更することはありません
reversed()
を使うと、リストを逆順にした新しいものが得られますが、元のリストはそのままです。例えば、次のようなリストがあった場合:
lst = [1, 2, 3, 4]
reversed()
を使って逆順にしたからと言って、元のリスト(lst
)が変わるわけではありません。lst
はそのままで、逆順にした結果が欲しい場合は、新しいリストを作る必要があります。
# reversedを使って逆順のリストを作っても、元のリストは変わらない
reversed_lst = list(reversed(lst))
print(reversed_lst) # [4, 3, 2, 1]
print(lst) # [1, 2, 3, 4] ※ 元のリストは変わっていない
2. イテレータを返すため
reversed()
が返すのは「イテレータ」というもので、これは順番に一つずつリストの要素を渡してくれる「箱」のようなものです。イテレータ自体は直接リストとして使うことはできません。
例えば、reversed()
を使うと、次のように逆順にしたものを一度に取り出すことができません。
reversed_lst = reversed(lst)
これだけではイテレータなので、中身を見たり使ったりするにはlist()
で囲む必要があります。
# reversedはイテレータなので、リストに変換する必要がある
print(list(reversed_lst)) # [4, 3, 2, 1]
まとめ
-
reversed()
は元のリストを変更せず、逆順にしたイテレータを返す関数です。逆順にする際にはリストに変換するか、for
ループで利用する必要があります。 - リストの一部分を逆順にしたい場合は、スライスを使って変更することができます。
-
f()
関数を正しく作成するためには、戻り値を返すようにするか、リストを直接変更する方法を選ぶと良いでしょう。
このブログ記事が、Pythonのリスト操作を学ぶ一助となれば嬉しいです。