2013-03-23 3 views
1

Рассмотрим следующий код:Являются ли возможности списком списков python действительно асимметричными? не

>>> a = [0, 1, 2] 
>>> for i in range(len(a)): 
>>> print a[0:i] 

[] 
[0] 
[0, 1] 

Однако, когда я переверните код, чтобы взять кусочки от другого конца списка, он больше не работает:

>>> for i in range(len(a)): 
>>> print a[-i:] 

[0, 1, 2] 
[2] 
[1, 2] 

Единственный способ сделать второй фрагмент кода для работы, похоже, заключается в том, чтобы повернуть вспять список, сделать это первым путем и отменить каждую часть перед ее печатью. Есть лучший способ сделать это? Я иногда использую этот тип цикла, и я бы хотел, чтобы мой код был как можно более чистым.

EDIT: В обоих циклах я повторяю слева направо. Если я переворачиваю направление итерации для второго цикла, он работает. Если бы я изменить направление итерации для первого цикла, она также имеет ту же икоту в качестве второго контура:

>>> for i in range(len(a)): 
>>> print a[i-1::-1] 

[2, 1, 0] 
[0] 
[1, 0] 

ответ

8

Первой итерации, вы нарезка в -0, который так же, как нарезка из 0. Только вторую итерацию вы нарезаете как -1, затем -2.

Может быть, вы могли бы использовать начальный диапазон при отрицательном индексе:

for i in range(-len(a), 0): 
    print a[-i:] 
+3

Arg - Когда вы появились здесь? Теперь, как я должен FGITW что-нибудь? (+1 кстати) – mgilson

+0

Он прячется в тени. xD – TerryA

+0

Нельзя доверять войлочным ниндзям .. – 2013-03-23 23:04:32

0

Перевернутой нарезка не может быть полностью симметрична в Python из 0 на основе индексации. В частности, невозможно отличить -0 от 0. Но симметричный случай использования в массивах с индексированием по 0 будет определять, что если 0-й элемент сначала слева, то -0-й элемент (т. Е. отрицательный 0) является первым справа, но поскольку 0 и -0 являются одним и тем же объектом, это создает проблему.

Рассмотрим две ориентации индексов список по:

Нападающий: первый элемент находится в положении 0, второй пункт в положении 1, ..., последний элемент в положении N-1

назад: первый элемент находится в положении -1, второй с -2, ..., последний элемент в положении -n

отрицательный индекс обозначения поэтому сокращенная для длины (индекса): collection[-i] == collection[len(collection) - i]

Или, бок о бок, то индексация:

[0, 1, 2,...,n-1] 
[-n,..., -3, -2, -1 ] 

Где оба указанных выше показателей фактически идентичны.

Чтобы выполнить симметричную операцию, ваш оператор среза необходимо правильно учесть эту индексирование схеме:

оригинальный ломтик: a[0:i] == I элементы из левого конца (при 0) с размером шага 1 == a[0:i:1]

обратный срез: I элементы из правого конца (в -1) с размером шага -1.

Таким образом, правильный срез с другого конца будет a[-1:-1-i:-1]

Обратите внимание, что значение остановки здесь является негативом I, смещение на -1 для учета -1, ориентированного на обращенно-индексации, которая необходимо, поскольку мы генерируем i, используя список в прямом направлении (например, функцию диапазона.)

a = range(3) # [0,1,2] 
for i in range(len(a)): 
    # forward case, next to backward case 
    print a[:i], a[-1:-1-i:-1] 
# [] [] 
# [0] [2] 
# [0, 1] [2, 1]