Неправильная последовательность символов на выходе

def sort_string(s):
    s = list(s)#['c', 'b', 'a', ' ', 'C', 'c', ' ', 'C']
    symbol_set = sorted([symbol for symbol in s if symbol.isalpha()], key=str.lower)
    #['a', 'b', 'c', 'C', 'c', 'C']
    id_set=[]
    n=0
    for i in s:
        if i.isalpha():
            id_set.append(s.index(i,n))
        n+=1 
    #id_set =[0, 1, 2, 4, 5, 7]                            
    set=zip(id_set,symbol_set)
    for i, j in set:
        s.remove(j)
        s.insert(i, j)
        #0 a
        #1 b
        #4 C
        #5 c
        #7 C
    return ''.join(s)#<---------


print(sort_string('cba Cc C'))

Здравствуйте, понадобилось написать небольшую программку для вывода отсортированной строки, затрагивая только положение букв. В данном случае, на вход даётся cba Cc C и на выходе получаем ab cc CC, хотя должны abcCcC. Втыкая принт куда только можно я выяснил, что всё идет как надо до помеченной строки. Моих знаний не хватает для решения этой проблемы и в интернете ничего дельного не смог найти.


Ответы (2 шт):

Автор решения: 4500zenja

Если Вы используете в цикле remove(), он уберёт первое нахождение данного элемента в массиве s. Учитывая, что у Вас есть несколько символов c и C, данная затея может легко всё запороть, так что желательно удалять элементы массива не по значению, а по индексу — если подумать, то мы тогда не будем влиять на элементы, следующие после текущего: у них остаются такие же индексы.

И тут на помощь приходит pop(), прекрасно выполняющую функцию удалению элемента массива по его индексу.

def sort_string(s):
  s = list(s)
  symbol_set = sorted([symbol for symbol in s if symbol.isalpha()], key=str.lower)
  id_set=[]
  n=0
  for i in s:
    if i.isalpha():
      id_set.append(s.index(i,n))
    n+=1                          
  set=zip(id_set,symbol_set)
  for i, j in set:
    s.pop(i) # меняем вот туть
    s.insert(i, j)
  return ''.join(filter(lambda c: not c.isspace(), s))
  # заодно ещё убираем все пробелы с помощью filter
  # https://realpython.com/python-filter-function
  # https://pythonz.net/references/named/str.isspace/
  
print(sort_string('cba Cc C')) #abcCcC
→ Ссылка
Автор решения: Namerek
from itertools import filterfalse

value = 'c#ba |Cc C'

def spec_sort(val: str):
    no_alpha_idx = []
    def parse(source_value: str):
        for n, sym in enumerate(filterfalse(str.isspace, source_value)):
            if sym.isalpha():
                yield sym
            else:
                no_alpha_idx.append(
                    (n, sym)
                )

    s = sorted(parse(val), key=str.lower)

    for i, v in no_alpha_idx:
        s.insert(i, v)
    return ''.join(s)

result_string = spec_sort(value)
print(
    result_string
)
# a#bc|CcC
→ Ссылка