Slice Assignment with a String in a List

Question:

I did quite a bit of perusing, but I don’t have a definite answer for the concept that I’m trying to understand.

In Python, if I take a list, such as:

L1=['muffins', 'brownies','cookies']

And then attempted to replace the first pointer to an object in the list, namely ‘muffins’ by using the code:

L1[0:1] = 'cake'

I would get a list L1:

['c', 'a', 'k', 'e', 'brownies', 'cookies']

Yet if I took the same list and performed the operation (now with the 4 elements from the string cake):

L1[0:4] = ['cake'] # presumably, it's now passing the string cake within a list? (it passed into the modified list shown above)

I get the output I initially desired:

['cake', 'brownies', 'cookies']

Can anyone explain why that is, exactly?
I’m assuming that when I take cake initially without it being in a “list”, it breaks the string into its individual characters to be stored as references to those characters as opposed to a single reference to a string…

But I’m not entirely sure.

Asked By: Noc

||

Answers:

If you specify a slice, the righthand side is presumed to be a list/tuple (actually, any iterable – but watch out for generators that produce an indefinite number of values).

To replace an item in a list, use:

my_list[0] = "cake"

(You could also do

my_list[0:1] = ["cake"]

if you really want to use a list slice.

See also:
slice assignment

Answered By: Art Swri

Two important points:

  1. Slice assignment takes an iterable on the right-hand side, and replaces the elements of the slice with the objects produced by the iterable.
  2. In Python, strings are iterable: iterating over a string yields its characters.

Thus

L1[0:1] = 'cake'

replaces the first element of L1 with the individual characters of 'cake'.

To replace the first element with the string 'cake', simply write:

L1[0] = 'cake'

or, using the slice assignment syntax:

L1[0:1] = ['cake']
Answered By: NPE

Think of strings as being a sequence container that stores characters. When you try to do assignments that way, it adds each item in the character sequence to the list. By wrapping “cake” in its own 1-element list first (let’s call it L2), you’re instead adding each element of L2 to L1 — it does not recursively split up sequence containers beyond the outermost sequence.

L1 = ['muffins', 'brownies','cookies']
L2 = ['cake']
L1[0:1] = L2
print L1
['cake', 'brownies', 'cookies']

This is also true for other nested sequence objects. Try experimenting with more nested sequence objects like this:

L3 = [['pie', 'eclairs'], ['bacon', 'chocolate']]
L1[0:1] = L3
print L1
[['pie', 'eclairs'], ['bacon', 'chocolate'], 'brownies', 'cookies']

It’s also worth noting that if you don’t care about order/positioning in the list, you can use append() and not have to worry about your string getting split up:

L1 = ['muffins', 'brownies','cookies']
L1.append('cake')
print L1
['muffins', 'brownies', 'cookies', 'cake']
Answered By: Joe Baker
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.