Why is a[:]=1 fundamentally different to a[:]='1'?
Question:
Please consider the two snippets of code (notice the distinction between string and integer):
a = []
a[:] = '1'
and
a = []
a[:] = 1
In the first case a
is ['1']
. In the second, I get the error TypeError: can only assign an iterable
. Why would using '1'
over 1
be fundamentally different here?
Answers:
Assigning to a slice requires an iterable on the right-hand side.
'1'
is iterable, while 1
is not. Consider the following:
In [7]: a=[]
In [8]: a[:]='abc'
The result is:
In [9]: a
Out[9]: ['a', 'b', 'c']
As you can see, the list gets each character of the string as a separate item. This is a consequence of the fact that iterating over a string yields its characters.
If you want to replace a range of a
‘s elements with a single scalar, simply wrap the scalar in an iterable of some sort:
In [11]: a[:]=(1,) # single-element tuple
In [12]: a
Out[12]: [1]
This also applies to strings (provided the string is to be treated as a single item and not as a sequence of characters):
In [17]: a[:]=('abc',)
In [18]: a
Out[18]: ['abc']
'1'
is a string, but it is iterable. It is like a list of characters. a[:]='1'
replaces the contents of the list a
with the content of the string '1'
. But 1
is an integer.
Python does not change the type.
Example:
print bool(1=='1') # --> False
Please consider the two snippets of code (notice the distinction between string and integer):
a = []
a[:] = '1'
and
a = []
a[:] = 1
In the first case a
is ['1']
. In the second, I get the error TypeError: can only assign an iterable
. Why would using '1'
over 1
be fundamentally different here?
Assigning to a slice requires an iterable on the right-hand side.
'1'
is iterable, while 1
is not. Consider the following:
In [7]: a=[]
In [8]: a[:]='abc'
The result is:
In [9]: a
Out[9]: ['a', 'b', 'c']
As you can see, the list gets each character of the string as a separate item. This is a consequence of the fact that iterating over a string yields its characters.
If you want to replace a range of a
‘s elements with a single scalar, simply wrap the scalar in an iterable of some sort:
In [11]: a[:]=(1,) # single-element tuple
In [12]: a
Out[12]: [1]
This also applies to strings (provided the string is to be treated as a single item and not as a sequence of characters):
In [17]: a[:]=('abc',)
In [18]: a
Out[18]: ['abc']
'1'
is a string, but it is iterable. It is like a list of characters. a[:]='1'
replaces the contents of the list a
with the content of the string '1'
. But 1
is an integer.
Python does not change the type.
Example:
print bool(1=='1') # --> False