Подтвердить что ты не робот

Нарезка реверсирования Python

Конкретный пример моего вопроса: "Как я могу получить" 3210 "в этом примере?"


>>> foo = '0123456'
>>> foo[0:4]
'0123'
>>> foo[::-1]
'6543210'
>>> foo[4:0:-1] # I was shooting for '3210' but made a fencepost error, that fine, but...
'4321'
>>> foo[3:-1:-1] # How can I get '3210'?
''
>>> foo[3:0:-1]
'321'

Кажется странным, что я могу написать foo [4: 0: -1], foo [5: 1: -1] и т.д. и получить то, что ожидаю, но нет способа написать срез, чтобы я get '3210'.

Временным способом сделать это будет foo [0: 4] [:: - 1], но это создает в нем два строковых объекта. Я буду выполнять эту операцию буквально миллиарды раз, поэтому каждая операция строки стоит дорого.

Мне нужно пропустить что-то глупое и легкое. Спасибо за вашу помощь!

4b9b3361

Ответ 1

Просто исключить индекс конечного диапазона...

>>> foo[3::-1]
'3210'

По иронии судьбы, о единственном варианте, я думаю, вы не пробовали.

Ответ 2

Если вы ищете нечто более понятное для человека, чем расширенное обозначение среза:

>>> foo = '0123456'
>>> ''.join(reversed(foo[0:4]))
'3210'

Ответ 3

Опустить конечный индекс в нотации вашего фрагмента:

>>> foo = '0123456'
>>> foo[3::-1]
'3210'

Если вам нужно сделать это много раз, создайте объект среза, который вы можете использовать снова и снова

>>> i = slice(3,None,-1)
>>> foo[i]
'3210'

Ответ 4

Вы можете использовать s[::-1] для изменения всей строки. Но если вы хотите поменять каждую подстроку на некоторую фиксированную длину, вы можете сначала извлечь подстроку, а затем перевернуть всю подстроку. Например, предположим, что нам нужно проверить, является ли каждая подстрока длиной 3 строки foo палиндром, мы можем сделать это следующим образом:

>>> foo = '0102030'
>>> for i in range(len(foo)-3):
...     if foo[i:i+3] == foo[i:i+3][::-1]:
...         print(foo[i:i+3], 'is a palindrome')
...     else:
...         print(foo[i:i+3], 'is not a palindrome')
...
010 is a palindrome
102 is not a palindrome
020 is a palindrome
203 is not a palindrome
030 is a palindrome

Если вы хотите проверить, является ли подстрока палиндром следующим образом:

if foo[i:i+3] == foo[i+2:i-1:-1]:
    ...

вы не сможете обрабатывать случай i 0, так как вы фактически сравниваете foo[0:3] с foo[2:-1:-1], что эквивалентно foo[2:n-1:-1], что, в свою очередь, является пустой строкой.

Единственным недостатком первого решения является то, что он использует немного больше памяти, но это не имеет большого значения.

Ответ 5

В дополнение к вышеупомянутым решениям вы можете сделать что-то вроде:

foo = '0123456'
foo[-4::-1]

Я предполагаю, что если foo будет менять длину, это может быть не лучшее решение, но если длина статическая, это сработает.

Ответ 6

После прочтения "технической документации" (здесь) - в частности предложение:

Если какая-либо граница отрицательна, длина последовательности добавляется к ней.

Я решил попробовать это, и он сработал:

>>> foo = '0123456'
>>> foo[3:-1-len(foo):-1]
'3210'
>>>

Итак, я думаю, что лучшим ответом на программное определение "конечной точки" было бы предоставление хорошо названной вспомогательной функции, которая бы давала понять, что ее аргументы всегда обрабатываются как положительные смещения, возможно, special_slice()

Я думаю, что ясность этого "особого" случая чрезвычайно важна, так как множество общих и значимых вариантов использования зависит от поведения по умолчанию отрицательных смещений (т.е. добавления длины к ним). Лично я часто использую конечную точку "-1", чтобы означать: остановка перед предыдущим элементом.

Итак, на основе вашего комментария:

..., который работает несколько следующим образом: foo [i: i-4: -1] и начинается с высокого "i" и спускается вниз.

Я мог бы сделать следующее:

def slice_by_len(data, start, length, step=1):
    end = start + length if step > 0 else start - length
    if end < 0:
        # Fix the negative offset to get what we really want
        end -= len(data)
    return data[start:end:step]

И затем вызовите его для каждого требуемого фрагмента:

foo_part = slice_by_len(foo, i, 4, -1)

Вышеизложенное может легко перейти в цикл по значениям 'i'

Ответ 7

s="this is my world"
pattern=re.findall(r'\S+',s)
a=[]
for i in range(len(pattern)):
    a.append((pattern[i][::-1]))
print (a)
print (" ".join(a))