Назначение среза со строкой в списке
Я довольно много изучал, но у меня нет определенного ответа на концепцию, которую я пытаюсь понять.
В Python, если я беру список, например:
L1=['muffins', 'brownies','cookies']
И затем попытался заменить первый указатель на объект в списке, а именно "кексы", используя код:
L1[0:1] = 'cake'
Я бы получил список L1:
['c', 'a', 'k', 'e', 'brownies', 'cookies']
Но если я взял тот же список и выполнил операцию (теперь с 4 элементами из торта):
L1[0:4] = ['cake'] # presumably, it now passing the string cake within a list? (it passed into the modified list shown above)
Я получаю желаемый результат:
['cake', 'brownies', 'cookies']
Может ли кто-нибудь объяснить, почему это так?
Я предполагаю, что когда я беру торт первоначально, не будучи в "списке", он разбивает строку на отдельные символы, которые будут храниться как ссылки на эти символы, а не на одну ссылку на строку...
Но я не совсем уверен.
Ответы
Ответ 1
Два важных момента:
- Назначение slice принимает итерацию с правой стороны и заменяет элементы среза на объекты, создаваемые итерабельным.
- В Python строки итерабельны: итерация по строке приводит к ее символам.
Таким образом,
L1[0:1] = 'cake'
заменяет первый элемент L1
на отдельные символы 'cake'
.
Чтобы заменить первый элемент строкой 'cake'
, просто напишите:
L1[0] = 'cake'
или, используя синтаксис назначения slice:
L1[0:1] = ['cake']
Ответ 2
Если вы указываете срез, правая сторона считается списком/кортежем (на самом деле, любой итерабельный - но следите за генераторами, которые производят неопределенное количество значений).
Чтобы заменить элемент в списке, используйте:
my_list[0] = "cake"
(Вы также можете сделать
my_list[0:1] = ["cake"]
если вы действительно хотите использовать фрагмент списка.
Вот пара других релевантных ссылок:
назначение фрагментов
больше назначения фрагментов
Ответ 3
Подумайте о строках как контейнере последовательности, в котором хранятся символы. Когда вы пытаетесь сделать назначения таким образом, он добавляет каждый элемент в последовательность символов в список. Сначала обернув "торт" в свой собственный 1-элементный список (позвоните ему L2), вместо этого вы добавляете каждый элемент L2 в L1 - он не рекурсивно разделяет контейнеры последовательностей за пределами самой внешней последовательности.
L1 = ['muffins', 'brownies','cookies']
L2 = ['cake']
L1[0:1] = L2
print L1
['cake', 'brownies', 'cookies']
Это также верно для других вложенных объектов последовательности. Попробуйте поэкспериментировать с более вложенными объектами последовательности, такими как:
L3 = [['pie', 'eclairs'], ['bacon', 'chocolate']]
L1[0:1] = L3
print L1
[['pie', 'eclairs'], ['bacon', 'chocolate'], 'brownies', 'cookies']
Также стоит отметить, что если вы не заботитесь о порядке/позиционировании в списке, вы можете использовать append()
и не беспокоиться о том, что ваша строка будет разделена:
L1 = ['muffins', 'brownies','cookies']
L1.append('cake')
print L1
['muffins', 'brownies', 'cookies', 'cake']