Python Language - Index & Slice

Python には様々な Data Type があり、それらの中には Index や Slice でその一部を取得したり、変更したりできるものがあります。

__3. An Informal Introduction to Python__
https://docs.python.org/3.9/tutorial/introduction.html

__5. Data Structures__
https://docs.python.org/3.9/tutorial/datastructures.html

ここでは、以下の代表的な Data Type について、使用方法の違いをご紹介します。

- String (Str)（文字列）
- List（リスト）
- Tuple（タプル）
- Set（集合）
- Dictionary (Dict)（辞書）

#### 環境
以下の Python 3.9 / Linux 環境で確認します。
```shell
$ uname -si
Linux x86_64

$ python3.9 -V
Python 3.9.13

$ python3.9
Python 3.9.13 (main, Jun 15 2022, 11:24:50)
[GCC 8.5.0 20210514 (Red Hat 8.5.0-13)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>>
```
以下の Data を使用します。
```shell
>>> STRING=''.join([str(x) for x in range(10)])
>>> STRING
'0123456789'
>>> type(STRING)
<class 'str'>

>>> LIST=[x for x in range(10)]
>>> LIST
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> type(LIST)
<class 'list'>

>>> TUPLE=tuple(x for x in range(10))
>>> TUPLE
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
>>> type(TUPLE)
<class 'tuple'>

>>> SET={x for x in range(10)}
>>> SET
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
>>> type(SET)
<class 'set'>

>>> DICT={x: x+100 for x in range(10)}
>>> DICT
{0: 100, 1: 101, 2: 102, 3: 103, 4: 104, 5: 105, 6: 106, 7: 107, 8: 108, 9: 109}
>>> type(DICT)
<class 'dict'>
```
```shell
>>> DATA=(STRING,LIST,TUPLE,SET,DICT)
>>> DATA
('0123456789', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], (0, 1, 2, 3, 4, 5, 6, 7, 8, 9), {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, {0: 100, 1: 101, 2: 102, 3: 103, 4: 104, 5: 105, 6: 106, 7: 107, 8: 108, 9: 109})
```
### Index
Index を使用して参照と代入ができるか確認してみます。
#### 参照
```shell
>>> for D in DATA:
...     type(D)
...     D
...     try:
...             D[0]
...             D[-1]
...     except:
...             print(f'Data Type {type(D)} : {sys.exc_info()}')
...
<class 'str'>
'0123456789'
'0'
'9'
<class 'list'>
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
0
9
<class 'tuple'>
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
0
9
<class 'set'>
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
Data Type <class 'set'> : (<class 'TypeError'>, TypeError("'set' object is not subscriptable"), <traceback object at 0x7f89079955c0>)
<class 'dict'>
{0: 100, 1: 101, 2: 102, 3: 103, 4: 104, 5: 105, 6: 106, 7: 107, 8: 108, 9: 109}
100
Data Type <class 'dict'> : (<class 'KeyError'>, KeyError(-1), <traceback object at 0x7f8907995500>)
```
Set は `TypeError("'set' object is not subscriptable")` が発生し、参照ができないことが分かります。
Dict は D[0] の値は取得できますが、D[-1] で `KeyError(-1)` が発生しています。これは、Dict Data の Key を Int型 としたため、D[0] は Key=0、D[-1] は Key=-1 となり後者が不正であったためであり、Dict で Index は使用できることが分かります。
```shell
>>> DICT
{0: 100, 1: 101, 2: 102, 3: 103, 4: 104, 5: 105, 6: 106, 7: 107, 8: 108, 9: 109}
>>> for D in DICT.items():
...     D
...
(0, 100)
(1, 101)
(2, 102)
(3, 103)
(4, 104)
(5, 105)
(6, 106)
(7, 107)
(8, 108)
(9, 109)
>>>
>>> for D in DICT.keys():
...     DICT[D]
...
100
101
102
103
104
105
106
107
108
109
```
#### 代入
```shell
>>> for D in DATA:
...     type(D)
...     D
...     try:
...             D[0] = 'Z'
...     except:
...             print(f'Data Type {type(D)} : {sys.exc_info()}')
...     finally:
...             D
...
<class 'str'>
'0123456789'
Data Type <class 'str'> : (<class 'TypeError'>, TypeError("'str' object does not support item assignment"), <traceback object at 0x7f8907995500>)
'0123456789'
<class 'list'>
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
['Z', 1, 2, 3, 4, 5, 6, 7, 8, 9]
<class 'tuple'>
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
Data Type <class 'tuple'> : (<class 'TypeError'>, TypeError("'tuple' object does not support item assignment"), <traceback object at 0x7f89079955c0>)
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
<class 'set'>
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
Data Type <class 'set'> : (<class 'TypeError'>, TypeError("'set' object does not support item assignment"), <traceback object at 0x7f8907995340>)
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
<class 'dict'>
{0: 100, 1: 101, 2: 102, 3: 103, 4: 104, 5: 105, 6: 106, 7: 107, 8: 108, 9: 109}
{0: 'Z', 1: 101, 2: 102, 3: 103, 4: 104, 5: 105, 6: 106, 7: 107, 8: 108, 9: 109}
```
Str、Tuple、Set は `TypeError("'***' object does not support item assignment")` が発生し、代入ができないことが分かります。

### Slice
Slice を使用して参照と代入ができるか確認してみます。
#### 参照
```shell
>>> for D in DATA:
...     type(D)
...     D
...     try:
...             D[:]
...     except:
...             print(f'Data Type {type(D)} : {sys.exc_info()}')
...
<class 'str'>
'0123456789'
'0123456789'
<class 'list'>
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
<class 'tuple'>
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
<class 'set'>
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
Data Type <class 'set'> : (<class 'TypeError'>, TypeError("'set' object is not subscriptable"), <traceback object at 0x7f8907995500>)
<class 'dict'>
{0: 100, 1: 101, 2: 102, 3: 103, 4: 104, 5: 105, 6: 106, 7: 107, 8: 108, 9: 109}
Data Type <class 'dict'> : (<class 'TypeError'>, TypeError("unhashable type: 'slice'"), <traceback object at 0x7f89079955c0>)
```
Set は Index の時と同様に `TypeError("'set' object is not subscriptable")` が発生し、参照ができないことが分かります。
Dict は `TypeError("unhashable type: 'slice'")` が発生し、参照ができないことが分かります。
#### 代入
```shell
>>> for D in DATA:
...     type(D)
...     D
...     try:
...             D[:2] = 'Y', 'Z'
...     except:
...             print(f'Data Type {type(D)} : {sys.exc_info()}')
...     finally:
...             D
...
<class 'str'>
'0123456789'
Data Type <class 'str'> : (<class 'TypeError'>, TypeError("'str' object does not support item assignment"), <traceback object at 0x7f8907995540>)
'0123456789'
<class 'list'>
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
['Y', 'Z', 2, 3, 4, 5, 6, 7, 8, 9]
<class 'tuple'>
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
Data Type <class 'tuple'> : (<class 'TypeError'>, TypeError("'tuple' object does not support item assignment"), <traceback object at 0x7f8907995400>)
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
<class 'set'>
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
Data Type <class 'set'> : (<class 'TypeError'>, TypeError("'set' object does not support item assignment"), <traceback object at 0x7f8907995440>)
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
<class 'dict'>
{0: 100, 1: 101, 2: 102, 3: 103, 4: 104, 5: 105, 6: 106, 7: 107, 8: 108, 9: 109}
Data Type <class 'dict'> : (<class 'TypeError'>, TypeError("unhashable type: 'slice'"), <traceback object at 0x7f8907995540>)
{0: 100, 1: 101, 2: 102, 3: 103, 4: 104, 5: 105, 6: 106, 7: 107, 8: 108, 9: 109}
```
Str、Tuple、Set は Index の時と同様に `TypeError("'***' object does not support item assignment")` が発生し、代入ができないことが分かります。
Dic は Slice の参照と同様に `TypeError("unhashable type: 'slice'")` が発生し、代入ができないことが分かります。