python 选择解释列表索引重新分配的动机是什么?

What is the motivation behind python's choice for interpretation of list indexing reassignment?

提问人:nmb 提问时间:4/2/2019 最后编辑:nmb 更新时间:4/2/2019 访问量:130

问:

我是 python 的新手(使用 python2.7),我不明白按索引更新列表时的以下行为以及哪些设计选择激发了该行为。我习惯于使用具有完全不同的默认行为的 R。此外,这是否特定于列表,或者是否会发生在任何可变序列中?数组呢?

如果我定义一个列表并想重新分配列表中的值,我会对某些行为感到困惑

>>> l = list(range(10))
>>> l[2:4] = [20, 30] # expected
>>> l                                                                           
[0, 1, 20, 30, 4, 5, 6, 7, 8, 9]                                                                          
>>> l[2] = [20, 30]   # expected
>>> l 
[0, 1, [20, 30], 30, 4, 5, 6, 7, 8, 9]                                                                      

# replacement length is longer than given index range, ignores end of given range on left side
>>> l = list(range(10))
>>> l[2:3] = [20, 30, 40]  # behaves as l[2:5]=[20,30,40] (unexpected)
>>> l
[0, 1, 20, 30, 40, 3, 4, 5, 6, 7, 8, 9] 

# replacement length is shorter than given index range, deletes unused index/values on left side
>>> l = list(range(10))
>>> l[2:9] = [20, 30, 40] # len(l)=6 (unexpected)
>>> l
[0, 1, 20, 30, 40, 9] 

# replacement length is longer than given range and outside of current length, appends to list.
>>> l = list(range(10))
>>> l[9:len(l)] = [20, 30, 40] # last value changed, len(l)= 12 (unexpected)
>>> l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 20, 30, 40]

在 R (3.2.3) 中,行为如下(注意,R 使用 1 作为第一个索引并包含最后一个索引,因此 2:3 是 python 的 2:4)

> l = 0:9
> l[2:3] = c(20, 30)
> l
 [1]  0 20 30  3  4  5  6  7  8  9
# replacement length is longer than given index range, values beyond given index range are ignored
> l = 0:9
> l[2] = c(20, 30)
Warning message:
In l[2] = c(20, 30) :
  number of items to replace is not a multiple of replacement length
> l
 [1]  0 20 2  3  4  5  6  7  8  9


# replacement length is longer than given index range, values beyond given index range are ignored
> l = 0:9
> l[2:3] = c(20, 30, 40)
Warning message:
In l[2:3] = c(20, 30, 40) :
  number of items to replace is not a multiple of replacement length
> l
 [1]  0 20 30  3  4  5  6  7  8  9

# replacement length is shorter than given index range, values repeated until index range is met
> l[2:9] = c(20,30,40)
> l
 [1]  0 20 30 40 20 30 40 20 30 9

# replacement length is longer than given index range, values beyond given index range are ignored
> l = 0:9
> l[9:length(l)] = c(20,30,40)
Warning message:
In l[9:length(l)] = c(20, 30, 40) :
  number of items to replace is not a multiple of replacement length
> l
 [1]  0  1  2  3  4  5  6  7 20 30

因此,简而言之,R 假设左侧给出的范围比右侧的范围更可信,并且忽略或重复右侧的值以满足赋值的左侧。

但 Python 到底在做什么?

Python R 列表 切片 序列

评论

0赞 hpaulj 4/2/2019
此行为记录在 docs.python.org/3/library/stdtypes.html#mutable-sequence-types,以及一些未测试的变体。对于某些切片,两边的长度必须匹配。但对于大多数人来说,RHS 只是替换了 LHS 上指定的切片。这使我们能够在内部缩小或增加列表。对我来说,这是合乎逻辑的行为,尽管我没有太多使用它。
0赞 nmb 4/2/2019
非常感谢您的链接!在注释中,它说 t 必须与它要替换的长度相同,但第二个示例表明没有遵守此规则。我承认 LHS 与 RHS 特权因语言而异,但我仍然不明白为什么要做出选择,因此我发现很难一概而论。
0赞 nmb 4/2/2019
另外,您能@hpaulj举一些情况,其中有切片要求,双方的长度必须匹配?在我早期探索用 python 重写我的 R 脚本时,我还没有找到一个。
0赞 hpaulj 4/2/2019
完全匹配的是脚注 1)。.也就是说,切片包括一个步骤(默认步骤 1 除外)。例如,试图替换其他每一个。s[i:j:k] = tl[::2] = [1,2]
0赞 stacksonstacks 4/2/2019
FWIW 来自 R,您可能想要 numpy

答: 暂无答案