mirror of
https://github.com/apachecn/ailearning.git
synced 2026-02-11 22:35:35 +08:00
250 lines
3.6 KiB
Markdown
250 lines
3.6 KiB
Markdown
# 索引和分片
|
||
|
||
## 索引
|
||
|
||
对于一个有序序列,可以通过索引的方法来访问对应位置的值。字符串便是一个有序序列的例子,**Python**使用 `[]` 来对有序序列进行索引。
|
||
|
||
In [1]:
|
||
|
||
```py
|
||
s = "hello world"
|
||
s[0]
|
||
|
||
```
|
||
|
||
Out[1]:
|
||
|
||
```py
|
||
'h'
|
||
```
|
||
|
||
**Python**中索引是从 `0` 开始的,所以索引 `0` 对应与序列的第 `1` 个元素。为了得到第 `5` 个元素,需要使用索引值 `4` 。
|
||
|
||
In [2]:
|
||
|
||
```py
|
||
s[4]
|
||
|
||
```
|
||
|
||
Out[2]:
|
||
|
||
```py
|
||
'o'
|
||
```
|
||
|
||
除了正向索引,**Python**还引入了负索引值的用法,即从后向前开始计数,例如,索引 `-2` 表示倒数第 `2` 个元素:
|
||
|
||
In [3]:
|
||
|
||
```py
|
||
s[-2]
|
||
|
||
```
|
||
|
||
Out[3]:
|
||
|
||
```py
|
||
'l'
|
||
```
|
||
|
||
单个索引大于等于字符串的长度时,会报错:
|
||
|
||
In [4]:
|
||
|
||
```py
|
||
s[11]
|
||
|
||
```
|
||
|
||
```py
|
||
---------------------------------------------------------------------------
|
||
IndexError Traceback (most recent call last)
|
||
<ipython-input-4-79ffc22473a3> in <module>()
|
||
----> 1 s[11]
|
||
|
||
IndexError: string index out of range
|
||
```
|
||
|
||
## 分片
|
||
|
||
分片用来从序列中提取出想要的子序列,其用法为:
|
||
|
||
```py
|
||
var[lower:upper:step]
|
||
```
|
||
|
||
其范围包括 `lower` ,但不包括 `upper` ,即 `[lower, upper)`, `step` 表示取值间隔大小,如果没有默认为`1`。
|
||
|
||
In [5]:
|
||
|
||
```py
|
||
s
|
||
|
||
```
|
||
|
||
Out[5]:
|
||
|
||
```py
|
||
'hello world'
|
||
```
|
||
|
||
In [6]:
|
||
|
||
```py
|
||
s[1:3]
|
||
|
||
```
|
||
|
||
Out[6]:
|
||
|
||
```py
|
||
'el'
|
||
```
|
||
|
||
分片中包含的元素的个数为 `3-1=2` 。
|
||
|
||
也可以使用负索引来指定分片的范围:
|
||
|
||
In [7]:
|
||
|
||
```py
|
||
s[1:-2]
|
||
|
||
```
|
||
|
||
Out[7]:
|
||
|
||
```py
|
||
'ello wor'
|
||
```
|
||
|
||
包括索引 `1` 但是不包括索引 `-2` 。
|
||
|
||
lower和upper可以省略,省略lower意味着从开头开始分片,省略upper意味着一直分片到结尾。
|
||
|
||
In [8]:
|
||
|
||
```py
|
||
s[:3]
|
||
|
||
```
|
||
|
||
Out[8]:
|
||
|
||
```py
|
||
'hel'
|
||
```
|
||
|
||
In [9]:
|
||
|
||
```py
|
||
s[-3:]
|
||
|
||
```
|
||
|
||
Out[9]:
|
||
|
||
```py
|
||
'rld'
|
||
```
|
||
|
||
In [10]:
|
||
|
||
```py
|
||
s[:]
|
||
|
||
```
|
||
|
||
Out[10]:
|
||
|
||
```py
|
||
'hello world'
|
||
```
|
||
|
||
每隔两个取一个值:
|
||
|
||
In [11]:
|
||
|
||
```py
|
||
s[::2]
|
||
|
||
```
|
||
|
||
Out[11]:
|
||
|
||
```py
|
||
'hlowrd'
|
||
```
|
||
|
||
当step的值为负时,省略lower意味着从结尾开始分片,省略upper意味着一直分片到开头。
|
||
|
||
In [12]:
|
||
|
||
```py
|
||
s[::-1]
|
||
|
||
```
|
||
|
||
Out[12]:
|
||
|
||
```py
|
||
'dlrow olleh'
|
||
```
|
||
|
||
当给定的upper超出字符串的长度(注意:因为不包含upper,所以可以等于)时,Python并不会报错,不过只会计算到结尾。
|
||
|
||
In [13]:
|
||
|
||
```py
|
||
s[:100]
|
||
|
||
```
|
||
|
||
Out[13]:
|
||
|
||
```py
|
||
'hello world'
|
||
```
|
||
|
||
## 使用“0”作为索引开头的原因
|
||
|
||
### 使用`[low, up)`形式的原因
|
||
|
||
假设需要表示字符串 `hello` 中的内部子串 `el` :
|
||
|
||
| 方式 | `[low, up)` | `(low, up]` | `(lower, upper)` | `[lower, upper]` |
|
||
| --- | --- | --- | --- | --- |
|
||
| 表示 | `[1,3)` | `(0,2]` | `(0,3)` | `[1,2]` |
|
||
| 序列长度 | `up - low` | `up - low` | `up - low - 1` | `up - low + 1` |
|
||
|
||
对长度来说,前两种方式比较好,因为不需要烦人的加一减一。
|
||
|
||
现在只考虑前两种方法,假设要表示字符串`hello`中的从头开始的子串`hel`:
|
||
|
||
| 方式 | `[low, up)` | `(low, up]` |
|
||
| --- | --- | --- |
|
||
| 表示 | `[0,3)` | `(-1,2]` |
|
||
| 序列长度 | `up - low` | `up - low` |
|
||
|
||
第二种表示方法从`-1`开始,不是很好,所以选择使用第一种`[low, up)`的形式。
|
||
|
||
### 使用0-base的形式
|
||
|
||
> Just to beautiful to ignore.
|
||
> ----Guido van Rossum
|
||
|
||
两种简单的情况:
|
||
|
||
* 从头开始的n个元素;
|
||
|
||
* 使用0-base:`[0, n)`
|
||
* 使用1-base:`[1, n+1)`
|
||
* 第`i+1`个元素到第`i+n`个元素。
|
||
|
||
* 使用0-base:`[i, n+i)`
|
||
* 使用1-base:`[i+1, n+i+1)`
|
||
|
||
1-base有个`+1`部分,所以不推荐。
|
||
|
||
综合这两种原因,**Python**使用0-base的方法来进行索引。 |