Не могу привести значение всех слов в копии списка к нижнему регистру
Пытаюсь привести значение всех слов в копии списка к нижнему регистру, но не получается. Подскажите пожалуйста где я допустил ошибку.
Python 3.8.1
users = ['andrew', 'caRolina', 'davID', 'denis', 'yAKUT8', "jaNE",'AdMiN']
new_users = users[:]
for name in new_users:
name = name.lower()
print(users)
print(new_users)
Ожидаемый результат
['andrew', 'caRolina', 'davID', 'denis', 'yAKUT8', 'jaNE', 'AdMiN']
['andrew', 'carolina', 'david', 'denis', 'yakut8', 'jane', 'admin']
Фактический результат
['andrew', 'caRolina', 'davID', 'denis', 'yAKUT8', 'jaNE', 'AdMiN']
['andrew', 'caRolina', 'davID', 'denis', 'yAKUT8', 'jaNE', 'AdMiN']
Ответы (3 шт):
В Python списки являются изменяемыми типами данных, поэтому Вы можете модифицировать элементы в процессе итерации, обращаясь к ним по индексу:
for i in range(len(new_users)):
new_users[i] = new_users[i].lower()
Либо используйте списковое включение для генерации нового списка, как предложил S. Nick:
new_users = [ name.lower() for name in users ]
Замените вторую строку на
new_users = users.copy()
Объяснением этому является главный принцип ООП, а точнее его расширение в Python. В ООП всё является объектами. А переменные являются лишь ссылками на объекты. Написав new_users = users[:], вы добавили всего лишь новую ссылку на список, на который ссылается users. Метод списка copy() возвращает новый список, но с такими же значениями внутри него
Основная проблема - это то, что когда вы пишете name.lower() вы создаёте новую строку и переменная name после присваивания ей этого значения начинает указывать на новую строку, а не на текущий элемент списка, на который она указывала до того. Обратно в текущий элемент списка new_users эта строка не помещается автоматически. Чтобы она там появилась, надо сделать явное присвоение текущему элементу списка. Таким образом, чтобы ваш код заработал минимальное исправление будет выглядеть, например, так:
users = ['andrew', 'caRolina', 'davID', 'denis', 'yAKUT8', "jaNE",'AdMiN']
new_users = users[:]
for i,name in enumerate(new_users):
name = name.lower()
new_users[i] = name
print(users)
print(new_users)
Но более pythonic-way, конечно, воспользоваться советами из других ответов и комментариев и написать всё в одну строку через map либо через списковое включение. Я просто объяснил что именно в вашем коде не срабатывает.
P.S. Кроме всего прочего, модифицировать "на ходу" именно тот список, по которому вы итерируетесь - не очень хорошая манера, лучше так не делать, хотя в данном случае это работает.