Aka*_*ph7 72 python sequence slice python-3.x range-checking
所以我只是遇到了一些奇怪的Python特性,并想要对它进行一些澄清.
以下数组操作有点有意义:
p = [1,2,3]
p[3:] = [4]
p = [1,2,3,4]
Run Code Online (Sandbox Code Playgroud)
我想它实际上只是将这个值附加到最后,对吗?
但是,我为什么要这样做呢?
p[20:22] = [5,6]
p = [1,2,3,4,5,6]
Run Code Online (Sandbox Code Playgroud)
更是如此:
p[20:100] = [7,8]
p = [1,2,3,4,5,6,7,8]
Run Code Online (Sandbox Code Playgroud)
这似乎是错误的逻辑.这似乎应该抛出错误!
任何解释?
- 这只是Python的奇怪之处吗?
- 有目的吗?
- 我是否以错误的方式思考这个问题?
Ray*_*ger 76
切片逻辑自动将索引剪切为序列的长度.
为方便起见,允许切片索引延伸超过端点.要对每个表达式进行范围检查然后手动调整限制将是一件痛苦的事情,因此Python会为您完成.
考虑想要显示不超过文本消息的前50个字符的用例.
简单的方法(Python现在做什么):
preview = msg[:50]
Run Code Online (Sandbox Code Playgroud)
或者艰难的方式(自己做限制检查):
n = len(msg)
preview = msg[:50] if n > 50 else msg
Run Code Online (Sandbox Code Playgroud)
手动实现调整终点的逻辑很容易忘记,容易出错(在两个地方更新50),会很啰嗦,而且会很慢.Python将该逻辑移动到其内部,其中它是自动,快速和正确的.这是我喜欢Python的原因之一:-)
OP还想知道允许分配的基本原理,例如p[20:100] = [7,8]
分配目标的长度(80)与替换数据长度(2)不同.
通过类比字符串来看最简单的动机是最简单的.考虑,"five little monkeys".replace("little", "humongous")
.请注意,目标"小"只有六个字母而"humongous"有九个字母.我们可以对列表做同样的事情:
>>> s = list("five little monkeys")
>>> i = s.index('l')
>>> n = len('little')
>>> s[i : i+n ] = list("humongous")
>>> ''.join(s)
'five humongous monkeys'
Run Code Online (Sandbox Code Playgroud)
这一切都归结为方便.
在引入copy()和clear()方法之前,这些曾经是流行的习语:
s[:] = [] # clear a list
t = u[:] # copy a list
Run Code Online (Sandbox Code Playgroud)
即使是现在,我们在过滤时使用它来更新列表:
s[:] = [x for x in s if not math.isnan(x)] # filter-out NaN values
Run Code Online (Sandbox Code Playgroud)
希望这些实际的例子能够很好地理解为什么切片的工作原理.
iz_*_*iz_ 23
该文件有你的答案:
s[i:j]
:的切片s
从i
至j
(注(4))(4)的切片
s
从i
到j
被定义为物品的索引序列k
,使得i <= k < j
.如果i
或j
大于len(s)
,请使用len(s)
.如果i
省略或None
使用0
.如果j
省略或None
使用len(s)
.如果i
大于或等于j
,则切片为空.
确认此行为的文档IndexError
:
例外
IndexError
当序列下标超出范围时引发.(切片索引被静默截断以落在允许的范围内;如果索引不是整数,
TypeError
则会被提升.)
基本上,像这样的东西p[20:100]
正在减少p[len(p):len(p]
.p[len(p):len(p]
是列表末尾的空切片,并为其分配列表将修改列表的末尾以包含所述列表.因此,它的作用就像追加/扩展原始列表一样.
此行为与将列表分配给原始列表中任何位置的空切片时的行为相同.例如:
In [1]: p = [1, 2, 3, 4]
In [2]: p[2:2] = [42, 42, 42]
In [3]: p
Out[3]: [1, 2, 42, 42, 42, 3, 4]
Run Code Online (Sandbox Code Playgroud)