Я пытаюсь написать программу, которая берет строку и заменяет определенные символы другими строками. (A->AB) и (B->A) в этом случае. Когда я запускаю его, я ожидаю, что будет возвращена окончательная строка, но вместо этого ничего не возвращается.
def createSystem(seed,depth):
startString = seed
endString = ""
for i in range(depth):
endString = processString(startString)
startString = endString
return endString
def processString(oldstr):
newstr = ""
for char in oldstr:
newstr=newstr+applyrules(oldstr)
return(newstr)
def applyrules(oldstr):
output = ""
for char in oldstr:
if char= = "A":
output.join("AB")
elif char= = "B":
output.join("A")
return(output)
print(createSystem("AB",1))
В этом примере я ожидал бы, что семя «AB» создаст строку «ABA», однако на консоль ничего не возвращается. Почему это? Заранее спасибо! - Эли
Обновлено: Программа компилируется и не выдает никаких ошибок.
Кстати, код делает создает строку - просто пустую.






Похоже, вы ожидаете, например,
output = ""
output.join("AB")
означает: «output — пустая строка; теперь заставьте output стать результатом добавления 'AB' в конец существующего output».
Это не.
Это означает: «output — пустая строка; теперь создайте новую строку, поместив существующую output между каждым символом 'AB', и выбросьте эту новую строку (не давайте ей имени)».
В Python строки — это неизменный — никакие действия с ними не могут изменить их содержимое на месте, как со списком. Вы должны использовать операцию, которая создает новую строку, и переназначить результат. Кроме того, метод join используется для получения целых строк последовательность и их объединения, например:
' '.join(['a', 'b', 'c']) # produces 'a b c'
Код не вызывает ошибку, потому что строка Python также является допустимой последовательностью строк (каждая из которых состоит из одного символа). Это особое поведение строк, не разделяемое другими последовательностями.
Чтобы использовать этот метод здесь, вам нужно создать последовательность фрагментов 'AB' и 'A' и просто вызвать ''.join (т. е. мы поместим пустую строку между каждым фрагментом), чтобы получить результат напрямую. Мы можем сделать это с помощью выражение генератора. Это выглядит так:
def process_string(oldstr):
return ''.join(
'AB' if char == 'A' else 'A'
for char in oldstr
)
(Обратите внимание на соглашение об именах для функции — см. ПКП 8 для стандартных соглашений о стиле в Python)
Это действительно все, что вам нужно. Или вы можете применить логику +=, которую вы имели в виду в исходном коде, для построения строки по частям (это менее эффективен):
def process_string(oldstr):
newstr = ''
for char in oldstr:
newstr += 'AB' if char == 'A' else 'A'
return newstr # parentheses are meaningless here.
Или вы можете использовать встроенную поддержку такого рода перевода строк, уже предоставленную классом строк (но это более неудобно, чем должно быть):
def process_string(oldstr):
return oldstr.translate(str.maketrans({'A': 'AB', 'B': 'A'}))
Здесь str.maketrans вызывает метод класса, принадлежащий классу строк (с именем str и доступный автоматически как глобальный при запуске). Вы можете прочитать об этих методах в документации по языку: str.translate; str.maketrans.
Похоже, вы запутались и пытались сделать и то, и другое. Спасибо за попытку поместить логику правила преобразования в отдельную функцию (applyrules), но эта функция должна возвращать только фрагмент, соответствующий одному входному символу. (В конце концов, вы уже настроили перебор символов и спроектировали applyrules так, чтобы он принимал по одному символу за раз.) Работа, которую он выполняет, достаточно проста, поэтому — по крайней мере, на данный момент — отдельная функция на самом деле не нужна. необходимо (если это не поможет вам понять код).
В приведенных выше примерах я использовал тернарный условный оператор для представления логики выбора фрагмента замены для каждого входного символа. Это необходимо для подхода с выражением генератора, потому что вы пишете один выражение и вам некуда поместить блок if:/else:.
В качестве примечания: совершенно безопасно просто продолжать повторно использовать одно и то же имя для повторного назначения результата каждого шага в createSystem вместо того, чтобы перетасовывать вещи между двумя отдельными именами. Вы даже можете просто использовать имя входного параметра (seed).
@Andreas Хотя для новых программистов важно изучить основные методы отладки, я не думаю, что это поможет здесь; то, как написан код, наводит меня на некоторые неправильные представления о том, как на самом деле работают различные вещи.