Before answering your question you need to know two simple concepts. Subscription and Slicing.
Subscription.
This syntax of using a pair of brackets []
juxtaposed to an object is called Subscription and serves to select an item from a sequence(string, tuple or list) or mapping (dictionary). User-defined objects also support subscription if they are defined with a method __getitem__()
. Has the syntax:
objeto[ expressão ]
If the objeto
be a type of mapeamento
(dictionaries) to expressão
must
be an object whose value is one of the mapping keys
and the subscription selects the value in the mapping that corresponds to that
key.
When the objeto
is a type of Sequence(string, tuple or list) a expressão
shall be an integer number or a slice. An integer for when you want to select a single object within the sequence and a slice for when you want to select a range of items within the sequence.
Slicing.
Slicing is the act of selecting a range of items in a sequence type object. Its syntax:
objeto[ limite_inferior : limite_superior : passo ]
Where:
limite_inferior
represents the index of the first item to be included in the slice. The missing value is 0.
limite_superior
represents the index of the first item a NAY be included in the slice. Missing value is list length.
passo
represents the increment that will be added to the index of the previous item in the next item search. The missing value is 1.
Some simple examples:
>>> lista = [1,2,3,4,5,6,7,8,9,10]
>>> lista[::2]
[1, 3, 5, 7, 9]
>>> lista[:3]
[1, 2, 3]
>>> lista[3:]
[4, 5, 6, 7, 8, 9, 10]
Returning to the question.
When it comes to mutable sequence, strings do not apply because it is an immutable sequence, the subscription by slicing in addition to selecting items within a sequence can also be used to modify its content.
Be the operations:
s[i] = x
the item i
of s
is replaced by x
.
s[i:j:k] = t
the slice of s
going from i
until j
each k
elements, not including j
, shall be replaced by the content of everlasting t
.
s[i:i] = t
inserts the elements of the eternal t
in s
from the index i
.
del s[i:j:k]
remove from s
the slice going from i
until j
each k
elements, not including j
.
s[i:j:k] = []
the same as del s[i:j:k]
.
Aware of that in your question when you asked:
>>> lista = [1, 2, 3, 4]
>>> lista[2:2] = "Q"
>>> lista
[1, 2, 'Q', 3, 4]
You’re not just inserting a character into a list. Yes the result is a string containing a character inserted from the list but the logic that led to this result is not a simple insertion of an element in the list. When did you do lista[2:2] = "Q"
actually used this operation s[i:i] = t
which inserts the elements of the eternal t
in s
from the index i
, which implies that it was not the string "Q"
who was inserted into the list but the elements of the eternal "Q"
were inserted in the list from index two.
If the string as to be inserted is larger than a character it is not the string to be inserted but the elements that make up the eternal one. Example:
>>> lista = [1, 2, 3, 4]
>>> lista[2:2] = "Qualidade"
>>> lista
[1, 2, 'Q', 'u', 'a', 'l', 'i', 'd', 'a', 'd', 'e', 3, 4]
In the example can be seen the string "Qualidade"
, which is an eternal one, having its elements inserted one by one in the list from an index. If the intention is to insert the string `"Quality" within the list as a single element, the insertion of an iterable populated with the string must be done. Example:
>>> lista = [1, 2, 3, 4]
>>> lista[2:2] = ["Qualidade"]
>>> lista
[1, 2, 'Qualidade', 3, 4]
And it is not possible through this syntax to insert directly into a sequence an item that is not iterable. For example:
>>> lista = [1, 2, 3, 4]
>>> lista[2:2] = 2.5
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only assign an iterable
To insert a non-transferable item into a sequence it needs to be delimited into an eternal one. Example:
>>> lista = [1, 2, 3, 4]
>>> lista[2:2] = [2.5]
>>> lista
[1, 2, 2.5, 3, 4]
And the same considerations apply to your example lista[2:3] = "Q"
. Behold:
>>> lista = [1, 2, 3, 4]
>>> lista[2:3] = "Qualidade"
>>> lista
[1, 2, 'Q', 'u', 'a', 'l', 'i', 'd', 'a', 'd', 'e', 4]
Just remembering that lista[2:3] = "Qualidade"
is the operation s[i:j:k] = t
whose slice of s
going from i
until j
each k
elements, NAY including j
, shall be replaced by the contents of the t
.
To learn more read:
In this case what is occurring is that you are writing on top. In fact you are making a replacement.
– Danizavtz
If one of the answers below solved your problem and there was no doubt left, choose the one you liked the most and mark it as correct/accepted by clicking on the " " that is next to it, which also marks your question as solved. If you still have any questions or would like further clarification, feel free to comment.
– Augusto Vasques