ошибка, с которой я продолжаю сталкиваться с операторами for loops и return

#python #python-3.x #for-loop #return #return-value

#python #python-3.x #for-цикл #Возврат #возвращаемое значение

Вопрос:

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

Я приведу вам пример того, как это происходит с кодом, который я только что написал:

 def remove_exclamation(string):
string.split(' ')
for i in string:
    i.split()
    for char in i:
        if char == '!':
            del char
            ''.join(i)
            ' '.join(string)
return string
 

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

 >>>remove_exclamation('This is an example!')
'This is an example'
 

Но вместо этого я получаю это:

 >>>remove_exclamation('This is an example!')
'This is an example!'
 

Функция не удаляет восклицание в выходных данных и не делает того, что я намеревался сделать для нее сегодня.

Как я могу избежать этого, когда я создаю циклы for, вложенные циклы for и т. Д.?

Комментарии:

1. Оба ваших вывода идентичны. Но чего вам не хватает, так это повторной привязки string.split(',') string . Видите ли, строки неизменяемы в python.

2. Зачем проходить через все эти проблемы, когда они есть str.replace ?

3. Одна из ваших проблем заключается в том, что вы делаете i.split() , когда должны делать i = i.split() . В вашем коде результат никогда ничему не присваивается.

4. Ваш код обречен на неудачу, потому что вы никогда не присваиваете результат какой-либо операции. Также ваш отступ отключен, и я не уверен, что вы знаете, что del char это значит.

5. Да, list.join и str.split , — и действительно все строковые методы — возвращают новое значение . Они не изменяют данные на месте. Даже если предположить, что это правда, логика вашего кода отключена, но вы должны начать с этого.

Ответ №1:

Вы пишете свой код и формулируете свой вопрос так, как если бы можно было изменять строки в Python. Это невозможно.

Строки неизменяемы. Все функции, которые работают со строками, возвращают новые строки. Они не изменяют существующие строки.

Это возвращает список строк, но вы не используете результат:

 string.split(' ')
 

Это также:

 i.split()
 

Это удаляет переменную с именем char . Это не влияет на сам символ:

         del char
 

Это создает новую строку, которую вы не используете:

         ''.join(i)
 

Это также:

         ' '.join(string)
 

В целом, почти каждая строка кода неверна.

Вы, вероятно, хотели это сделать:

 def remove_exclamation(string):
    words = string.split(' ')
    rtn_words = []
    for word in words:
        word_without_exclamation = ''.join(ch for ch in word if ch != '!')
        rtn_words.append(word_without_exclamation)
    return ' '.join(rtn_words)
 

Но, в конце концов, это делает то же самое:

 def remove_exclamation(string):
    return string.replace('!', '')
 

Комментарии:

1. Нет необходимости разделять строку пробелом, если все, что вы хотите сделать, это удалить один символ — ''.join(ch for ch in string if ch != '!') достаточно (если вы не хотите использовать string.replace )

2. @AndreaCorbellini Конечно. Целью этого примера было исправить исходную функцию с минимальными изменениями, чтобы объяснить, как использовать результаты str.split and str.join .

Ответ №2:

Без четкого понимания намерений вашей функции и того, что вы пытаетесь сделать. У меня есть альтернатива ответу, который дал звоне.

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

 characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ "

test_string = "This is an example!"

test_string = ''.join(list(filter(lambda x: x in characters, test_string)))

print(test_string)
 

Это выводит:

Это пример

Обратите внимание, это версия Python 3.

Python 2, вам не нужен ''.join(list())

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

Вы даже можете сделать обратное:

 ignore_characters= "!"

test_string = "This is an example!"

test_string = ''.join(list(filter(lambda x: x not in ignore_characters, test_string)))

print(test_string)
 

Комментарии:

1. Вам также не нужен вызов list в Python 3. str.join принимает любую итерацию.

2. Кроме того, вы могли бы просто использовать filter(str.isalnum, test_string) или, по крайней мере, использовать a set в качестве контейнера вместо другой строки.

Ответ №3:

Строки неизменяемы в Python. И вы не можете их изменить. Однако вы можете переназначить там значения.

Вот в чем заключается ваша проблема. Вы никогда не переназначаете значение своих строк, когда вызываете .split() их.

Но в вашей программе есть и другие ошибки, такие как:

  • Ваш отступ
  • Тот факт, что вы просто возвращаете строку, переданную в функцию
  • Ваше использование del инструкции
  • и т.д.

Вместо этого создайте новую строку, выполнив итерацию по старой и отфильтровав символы, которые вам не нужны, с помощью понимания списка и ''.join() .

 def remove_exclamation(string):
    return ''.join([char for char in string if char != '!'])
 

Но, как @Moses уже сказал в комментариях, почему бы просто не использовать str.replace() ?:

string = string.replace('!', '')

Ответ №4:

 def remove_exclamation(string):

    #you think you are splitting string into tokens
    #but you are not assigning the split anywhere...
    string.split(' ')

    #and here you are cycling through individual _chars_ in string which was not affected by the split above ;-)
    for i in string:
        #and now you are splitting a 1-char string and again not assigning it.
        i.split()
 

И string по-прежнему является вашим входным параметром, который, как я предполагаю type str , принадлежит вам. И неизменный.

Кроме того, если бы вы импортировали / использовали string модуль, вы бы затеняли его

Большая часть вашей путаницы заключается в том, что вы знаете, когда методы изменяют объекты и когда они возвращают новый объект. В случае строк они никогда не изменяются, вам нужно присвоить результаты новой переменной.

Однако в списке, и join() где-то заставляет меня думать, что вы хотите использовать список, тогда методы обычно меняют объект на месте.

В любом случае, перейдем к вашему вопросу:

 def remove_exclamation(inputstring, to_remove="!"):
    return "".join([c for c in inputstring if c != to_remove])

print (remove_exclamation('This is an example!'))
 

выходной сигнал:
This is an example