LINUX.ORG.RU

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

 ,


0

1

Шалом, православные!

У меня есть строка «0123456789». Я хочу удалить из неё [0:3], [4:5] и [-2:-1]. Как бы это сделать поудобнее, чтобы индексы не смещались? Есть ли что-то готовое?


Ответ на: комментарий от Yak

«35679»

В чем проблема и при чем здесь не смещающиеся индексы

alienclaster ★★★
()

Напиши выражение, в котором указаны куски, которые ты хочешь оставить. Как-то так:

s1 = "0123456789"
s2 = s1[3:4] + ...
tailgunner ★★★★★
()

Или приведите строку к списку, удалите начиная с хвоста чего хотите, а потом сделайте ".join(...)

Но это извращение.

AIv ★★★★★
()
Ответ на: комментарий от AGUtilities

в Python стринги не мутируемые

Но replace возвращает новую строку. Но в данной задаче это тоже извращение (если конечно не нужно вынести какую то определенную последоваотельность символов, или неск последовательностей - тогда redeuce и replace в помощь).

AIv ★★★★★
()
Ответ на: комментарий от tkustov

RegExp?

безсмыслен и не нужен на этой задаче.

beka
()
Ответ на: комментарий от AIv

тогда redeuce и replace в помощь

это само собой. но входные стринги все равно остаются неизменёнными

AGUtilities ★★★
()
Ответ на: комментарий от AGUtilities

Ну всё, задача не решаема, ТС то заменить надо.

И у меня глаза болят от сообщения в котором русские только предлоги (ну или предлог и частица).

Kalashnikov ★★★
()
Ответ на: комментарий от AGUtilities

Преобразовать в список, сделать как предложили, потом join.

anonymous
()

Ты случайно не проходишь курс на coursera? Если проходишь, то таки топики поднимать нехорошо.

amazpyel ★★★
()

Кстати об извращениях.

>>> (lambda string, indices: ''.join(sorted(set(string).difference(set(''.join(s[x:y] for s in (string,) for x, y in (indices)))))))("0123456789", ([0,3], [4,5], [-2,-1]))
35679
>>> 
Тупо набыдлокодил «руками», не напрягая мозг :-[]

Virtuos86 ★★★★★
()
Ответ на: комментарий от Yak

Просто я прохожу, а там похожие задание ;) Да, там есть

amazpyel ★★★
()
Ответ на: комментарий от Virtuos86

Не, так работать не будет, Для твоей строки *2, результат будет не верным (случай повторяющихся последовательностей).

Надо что-то вроде

(lambda string, indices: ''.join((s[1] for s in enumerate(string) if not reduce(lambda x,y: x or (y[0] <= s[0] < y[1] ), indices, False))))("0123456789",((0,3),(4,5)))

Но с отрицательными индексами работать не будет, их надо дополнительно нормализовать, что лень.

aedeph_ ★★
()
Ответ на: комментарий от aedeph_

Вот так будет верно:

(lambda string, indices: ''.join((s[1] for s in enumerate(string) if not reduce(lambda x,y: x or ( (y[0] if y[0] >= 0 else y[0] + len(string) )<= s[0] < ( y[1] if y[1] >=0 else y[1]+len(string)) ), indices, False))))("0123456789",((0,3),(4,5),(-2,-1)))
aedeph_ ★★
()
Ответ на: комментарий от aedeph_

Спасибо, пойду покурю в сторонке, вот уж где ад и израиль. У тебя там лишняя пара скобок, в них ген. выражение обернуто (как будто кто заметит :). Я тут нестрашный вменяемый вариант набросал:

string = '0123456789'
indices = [[0,3], [4,5], [-2,-1]]
tmp = range(len(string))
for car, cdr in indices:
    if car < 0: car += len(string)
    if cdr < 0: cdr += len(string)
    for i in xrange(min(car, cdr), max(car, cdr)):
        if tmp[i]: tmp[i] = None
print ''.join(char for n, char in enumerate(string) if tmp[n])

Virtuos86 ★★★★★
()
Ответ на: комментарий от Virtuos86

Вот так оно покорректнее и получше будет ;|

string = '0123456789'
indices = [[0,3], [4,5], [-2,-1]]
tmp = range(len(string))
for car, cdr in indices:
    if car < 0: car += len(string)
    if cdr < 0: cdr += len(string)
    for i in xrange(min(car, cdr), max(car, cdr)):  tmp[i] = None
print ''.join(char for char, i in zip(string, tmp) if i is not None)

Virtuos86 ★★★★★
()
Ответ на: комментарий от Virtuos86

Да, логика в точности как у меня, но с мутабельными переменными.

Скобок у меня действительно без меры, наверняка они лишние есть и в приведении индексов. Просто люблю, что итерируем по generator expression выглядит как генератор. Также оборачиваю и тьюплы.

Кстати, а есть что-то лучше reduce'а для булевых произведений. То есть что-то типа forall(predicate, iterable), проверяющий True ли predicate от каждого в iterable? Я его реадизовал, как reduce(lambda x,y: x and predicate(y), iterable, True)

aedeph_ ★★
()
Ответ на: комментарий от aedeph_

То есть что-то типа forall(predicate, iterable), проверяющий True ли predicate от каждого в iterable?


Похоже на filter


help(filter)

Help on built-in function filter in module __builtin__:

filter(...)
filter(function or None, sequence) -> list, tuple, or string

Return those items of sequence for which function(item) is true. If
function is None, return the items that are true. If sequence is a tuple
or string, return the same type, else return a list.


Но я не знаю, что имеется в виду под

булевых произведений

Virtuos86 ★★★★★
()
Ответ на: комментарий от Virtuos86

Нет, фильтры-то я люблю, правда generator expression их функциональность поглащает. Я имел в виду именно замену reduce'у:

У нас есть 100 элементов в iterable, есть булева функция от каждого их них. Мы хотим узнать, для всех ли элементов значение её True. Это называется булево произведение (эдакая цепочка and'ов). Я могу написать это через reduce, но без шаманство он не будет заканчивать итерировать, когда нашёл False.

aedeph_ ★★
()
Ответ на: комментарий от Virtuos86

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

aedeph_ ★★
()
Ответ на: комментарий от Virtuos86

Как подсказали из зала, то, что мне было нужно, это any(iterable).

aedeph_ ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.