Какова мотивация выбора Python для интерпретации переназначения индексации списка? - PullRequest
3 голосов
/ 02 апреля 2019

Я новичок в 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?

...