I have read a snippet of code like this:
s = self.buffer_file.readline()
if s[-1:] == "\n":
return s
And if I do this:
s = 'abc'
In [78]: id(s[-1:]), id(s[-1])
Out[78]: (140419827715248, 140419827715248)
In [79]: id(s[-1:]) is id(s[-1])
Out[79]: False
In [80]: id(s[-1:]) == id(s[-1])
Out[80]: True
It doesn't make sense to me, the ID numbers are same, but the IDs are different. So they are different for some reason.
The difference is that the result of slicing a list is a list
x = [1, 2, 3]
print(x[-1]) # --> 3
print(x[-1:]) # --> [3]
The second case just happens to be a list of one element, but it's still a list.
Note however that Python doesn't have a char
type distinct from the str
type and this means that both element access and slicing on str
objects return another str
object:
print("abcd"[-1]) # --> "d"
print("abcd"[-1:]) # --> "d"
The only advantage of using for example s[-1:]
or s[:1]
with a string instead of s[-1]
and s[0]
is that the slice expressions will not raise a runtime error when acting on an empty string (something that element access does)... this may allow code simplification:
if len(s) > 0 and s[0] == '*': ...
if s[:1] == '*': ...
The key practical benefit to s[-1:]
rather than s[-1]
is that the former will produce an empty iterable rather than stopping with a traceback.
>>> 'hi'[-1:]
'i'
>>> 'hi'[-1]
'i'
>>> ''[-1:]
''
>>> ''[-1]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: string index out of range
This allows if s[-1:] == "\n":
to handle an empty line s
without preceding it with if s:
by simply evaluating to False
instead of generating an error that would need to be handled with a try..except
structure.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With