Pythonでリストの一部分を逆順にする方法と`reversed()`関数の解説

Pythonでリストを操作する際に、特定の範囲を逆順にしたいことがあるかもしれません。
今回は、その実現方法と、よく使われる`reversed()`関数について詳しく解説します。
（自分の備忘録的なものとして残します。同じ初級者が調べものをしている際お役に立てれば幸いです）

## リストの一部分を逆順にする関数の作成

例えば、リストの特定の範囲（`start`位置から`end`位置まで）を逆順に変更したい場合、どのようにコードを書くかを見ていきましょう。

### 最初に考えた方法（間違いが含まれています）

最初に書いたコードでは、次のような形で`reversed()`関数を使用してリストを逆順にしようとしました。
そして、私は、なんでNoneがでるの？？と疑問でした。
```python
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`が表示されてしまうのです。

#### 出力結果

```python
10
9
8
7
6
5
4
3
2
1
0
None
```

`None`が出力される理由は、`f()`関数内で`return`を使っていないため、関数呼び出し後に自動的に`None`が返されるためです。
確かに言われてみたら納得です。でも初心者なので、最初はわかりませんでした(笑)

---

## 正しい方法：リストの一部分を逆順に変更

### 1. リストを逆順にするだけの場合
リストをそのまま逆順にするには、`reversed()`を使うのが簡単です。以下はその例です。
```python
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`を使って新しいリストを返す方法もあります。例えば、以下のように書けます。
```python
def f(ls, intStart, intEnd):
    # 方法１: リストの一部分を逆順にして、新しいリストを作成
    newlist = ls[:intStart] + list(reversed(ls[intStart:intEnd+1])) + ls[intEnd+1:]

    # 方法２: reversed() の結果をそのまま返す（イテレータを返す）
    newlist = reversed(ls[intStart:intEnd+1])  # ★ イテレータのまま

    # 方法３: スライスを使ってリストの一部分を逆順にする
    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()`関数は逆順にしたリストを返し、元のリストは変更されません。

※方法１の詳細
first_part: ls[:intStart] で、intStartより前の部分を取り出します。
middle_part: ls[intStart:intEnd+1] で、逆順にする部分を取り出し、それを list(reversed(...)) で逆順にします。
last_part: ls[intEnd+1:] で、intEndより後ろの部分を取り出します。


---

## `reversed()`関数の詳しい解説
`reversed()`は、Pythonの組み込み関数で、指定したリストやシーケンス（タプルや文字列など）を逆順にした**イテレータ**を返します。元のリスト自体は変更されません。

### `reversed()`の使い方
```python
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()`を使うと、リストを逆順にした新しいものが得られますが、**元のリストはそのまま**です。例えば、次のようなリストがあった場合：
```python
lst = [1, 2, 3, 4]
```
`reversed()`を使って逆順にしたからと言って、元のリスト（`lst`）が変わるわけではありません。`lst`はそのままで、逆順にした結果が欲しい場合は、新しいリストを作る必要があります。
```python
# reversedを使って逆順のリストを作っても、元のリストは変わらない
reversed_lst = list(reversed(lst))
print(reversed_lst)  # [4, 3, 2, 1]
print(lst)  # [1, 2, 3, 4]  ※ 元のリストは変わっていない
```
#### 2. **イテレータを返すため**
`reversed()`が返すのは「イテレータ」というもので、これは**順番に一つずつ**リストの要素を渡してくれる「箱」のようなものです。イテレータ自体は**直接リストとして使うことはできません**。

例えば、`reversed()`を使うと、次のように**逆順**にしたものを一度に取り出すことができません。

```python
reversed_lst = reversed(lst)
```
これだけではイテレータなので、中身を見たり使ったりするには`list()`で囲む必要があります。
```python
# reversedはイテレータなので、リストに変換する必要がある
print(list(reversed_lst))  # [4, 3, 2, 1]
```

---
## まとめ
- `reversed()`は元のリストを変更せず、逆順にしたイテレータを返す関数です。逆順にする際にはリストに変換するか、`for`ループで利用する必要があります。
- リストの一部分を逆順にしたい場合は、スライスを使って変更することができます。
- `f()`関数を正しく作成するためには、戻り値を返すようにするか、リストを直接変更する方法を選ぶと良いでしょう。

このブログ記事が、Pythonのリスト操作を学ぶ一助となれば嬉しいです。