<style>
.blue {
color: blue;
font-weight: bold;
}
.red {
color: red;
font-weight: bold;
}
</style>
# 索引 - 切片(slice/スライス)
###### tags: `Python`
slice是對序列型對象(list, string, tuple)的一種進階索引方法。
:::info
スライスは、リストや文字列、タプルなどのシーケンスオブジェクトの要素をインデクスで指定して取得したり、別の値を代入したりできるワンランク上の方法のことです。
:::
## 索引範圍
正負索引共同形成Python的有效索引範圍。
:::info
インデックスの範囲
Pythonインデックスの有効範囲は正と負のインデックスによって確立されています。
:::

| 值 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| +index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| -index | -10 | -9 | -8 | -7 | -6 | -5 | -4 | -3 | -2 | -1 |
## 普通索引
<span class="blue">array[ index ]</span>,只取出序列array中<span class="red">一個對應index的值。</span>
:::info
インデックスを使った要素の取り出し
<span class="blue">array[ index ]</span>,array内から<span class="red">一つだけインデックスと一致する値を取り出す方法です。</span>
:::
```python=
>>> array = list(range(10))
>>> array
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> print(array[0])
0
```
## 切片索引
<span class="blue">array[ start : stop : step ]</span>取出序列array中<span class="red">對應[ start : stop : step ]範圍的值。</span>
**stop - start = 個數**
**step為負數:反向索引序列**
:::info
スライスを使った要素の取り出し
<span class="blue">array[ start : stop : step ]</span>リストarray内から<span class="red">特定の範囲[ start : stop : step ]の値を取得する方法です。</span>
**stop - start = 個数**
**stepを負の値で指定すると:後ろから逆順で要素を取得します。**
:::
```
>>> array = list(range(10))
>>> array
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> array[:5]
[0, 1, 2, 3, 4]
>>> array[5:]
[5, 6, 7, 8, 9]
>>> array[2:8]
[2, 3, 4, 5, 6, 7]
>>> array[::2]
[0, 2, 4, 6, 8]
>>> array[::-1]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
```
---
## 超出有效範圍的索引
:::info
有効範囲を超えたインデックス
:::
### 普通索引
**超出索引有效範圍**會丟出<span class="red">IndexError異常。</span>
:::info
インデックスを使った要素の取り出し
**インデックスの有効範囲を超えてしまうと**<span class="red">IndexError</span>が発生します。
:::
```python=
>>> array
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> array[10]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
>>> array[-11]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
```
### 切片索引
start 或 stop超出索引有效範圍時並**不會丟出異常**,而是假想**把索引範圍擴充到全體整數**,只是有效範圍以外的都是空值,擴充後再進行切片,最後把結果中所有的空元素忽略即可。
:::info
スライスを使った要素の取り出し
start、または stop がインデックスの有効範囲を超える際、**エラーは発生しません。** 何せ、仮定としてインデックスの範囲はパソコンの整数全体に拡張されます。但し、有効範囲以外の値は全部「空」と返ります。つまり、拡張が終わってから、スライスが行われ、最後に結果内の「空」要素が省略されることでエラーが発生しません。
:::
```python=
>>> array
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> array[-100:5]
[0, 1, 2, 3, 4]
>>> array[5:100]
[5, 6, 7, 8, 9]
>>> array[-100:100]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> array[100:1000]
[]
```
### start 的位置比 stop 還靠後的情況
不會丟出錯誤,會直接返回**空值**。
:::info
エラーは発生せずに、**空**が返ります。
:::
```python=
>>> array
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> array[6:5]
[]
```
### 省略start 跟 stop參數
start 跟 stop 都是可以省略不填,省略的情況下,Python會盡可能取最大區間。(start = 無限小, stop = 無限大)
:::info
startとstopの省略
startとstopは書かずに省略できます。省略した場合、Pythonは区間を可能な限り取得します。(start = 無限小、stop =無限大)
無限小:限りなく小さいこと。
:::
```python=
>>> array
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> array[:5]
[0, 1, 2, 3, 4]
>>> array[5:]
[5, 6, 7, 8, 9]
>>> array[100:]
[]
```
step為負數(start = 無限大, stop = 無限小)
:::info
stepが負数の場合(start = 無限大, stop = 無限小)
:::
```
>>> array
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> array[5::-1]
[5, 4, 3, 2, 1, 0]
>>> array[:4:-2]
[9, 7, 5]
>>> array[::-1]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
```
## 更改List的元素
利用`list[n:m] = x`這種寫法可以更改List的元素,n到m之間的個數不一定要跟x的個數一樣,個數不相同的情況下,list長度會有所改變。
```python=
>>> array
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> array[1:3] = ["one", "two",]
[0, 'one', 'two', 3, 4, 5, 6, 7, 8, 9]
>>> array[3:6] = ["three"]
[0, 'one', 'two', 'three', 6, 7, 8, 9]
```
利用此技巧可以對list做許多處理。
```python=
>>> array = list(range((5)))
[0, 1, 2, 3, 4]
>>> array[len(array):] = [5, 6] # 於list的最後面追加元素
[0, 1, 2, 3, 4, 5, 6]
>>> array[:0] = [-3, -2, -1] # 於list的最前面追加元素
[-3, -2, -1, 0, 1, 2, 3, 4, 5, 6]
>>> array[1:-1] = [] # 刪除list中的多個元素
[-3, 6]
```
---
## N = L v.s. N = L[:]
N = L是<span class="red">直接賦值</span>,會把列表L所在的記憶體位置直接給N,
N = L[:]才是<span class="red">複製一個列表</span>,將L的元素複製一份給N
若是N = L的情況,因為N和L指向同一個列表,修改N的元素會影響L
:::info
N = Lは<span class="red">参照渡し</span>,リストLのメモリ位置をNに渡します。
N = L[:]こそ<span class="red">リストをコピー</span>,Lの要素をNへとコピーします。
もしN = Lの場合,NとLは同じリストを参照しているので,Nの要素を変更すると、Lへ影響を与えます。
:::
```python=
L = ['C++', 'Python', 'Java']
N = L
N[1] = 'PHP'
print("L:{}".format(L))
print("N:{}".format(N))
```
**Results:**
```
L:['C++', 'PHP', 'Java']
N:['C++', 'PHP', 'Java']
```
若是N = L[:]的情況,因為N只是複製L的元素,修改N的元素不會影響L
:::info
もしN = L[:]の場合,NはただLの要素をコピーしただけなので,Nの要素を変更しても、Lへの影響はありません。
:::
```python=
L = ['C++', 'Python', 'Java']
N = L[:]
N[1] = 'PHP'
print("L:{}".format(L))
print("N:{}".format(N))
```
**Results:**
```
L:['C++', 'Python', 'Java']
N:['C++', 'PHP', 'Java']
```
---
## Question - 1
為了更客觀的評分,請去除最高分跟最低分。
:::info
より客観的に評価したいため、最高点と最低点を除いて下さい。
:::
```
原本:
scores = [10, 10, 3, 10, 9, 10, 2, 10, 6, 5]
返回:
[3, 5, 6, 9, 10, 10, 10, 10]
```
**Example:**
```python=
def judge(scores):
return sorted(scores)[1:-1]
scores = [10, 10, 3, 10, 9, 10, 2, 10, 6, 5]
print(judge(scores))
```
---
## 參考
[原理](https://zhuanlan.zhihu.com/p/79752359)
[JP](https://note.nkmk.me/python-slice-usage/)
[順序](https://stackoverflow.com/questions/509211/understanding-slice-notation)
[スライス操作についてまとめ](https://qiita.com/tanuk1647/items/276d2be36f5abb8ea52e)