Weired behaviour - The slice of empty string not return an error
dn
PythonList at DancesWithMice.info
Mon Oct 31 00:05:44 EDT 2022
On 31/10/2022 03.59, Yassine Nasri wrote:
> PS: The ''[::] should return an error logically.
>
> Le dim. 30 oct. 2022 à 15:57, Yassine Nasri <yassine.naasri at gmail.com> a
> écrit :
>
>> Hello,
>>
>> len('') # => 0''[0] # => error''[::] # => ''''[::] # <=> ''[0:len(''):1]
>>
>> the syntax of slice:
>>
>> slice(start, end, step)
>>
>> The start in ''[::] equivalent at index 0 of the ''
>>
>> Since the index 0 of '' returns an error.
>>
>> The ''[::] should not return an error logically.
Perhaps it will help to say:
- "indexing" one "element" from a "sequence" will yield a single result
of the type of that element
- "slicing" a "sequence" will yield a result of the same type as the
original sequence
The corollary to the first is expected: that if there is no element at
the stated index/position, something is wrong.
However, what is not necessarily apparent, is that because the result is
of the same type as the original sequence, and an empty-sequence is
perfectly legal; so is it possible to slice something and receive back
'nothing'.
The second 'saying' is to use the correct jargon:
- in a[ i ] i is an "index"
- in a[ i:j ] i and j are "parameters"
A parameter does not (also) need to be a legal index!
This is proven (as you have discovered (but is difficult to read, above):
>>> sequence = []
>>> len( sequence )
0
>>> sequence[ 0 ]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
>>> sequence[ 0:1 ]
[]
The question (and assertion) are discussed in the manual:
«Sequences
These represent finite ordered sets indexed by non-negative
numbers. The built-in function len() returns the number of items of a
sequence. When the length of a sequence is n, the index set contains the
numbers 0, 1, …, n-1. Item i of sequence a is selected by a[i].
Sequences also support slicing: a[i:j] selects all items with index
k such that i <= k < j. When used as an expression, a slice is a
sequence of the same type. This implies that the index set is renumbered
so that it starts at 0.
Some sequences also support “extended slicing” with a third “step”
parameter: a[i:j:k] selects all items of a with index x where x = i +
n*k, n >= 0 and i <= x < j.
»
Thus, an index must point to an existing element, whereas the parameters
of a slice need not. If the slice-specification calls for elements
'beyond' the end of the sequence, then the result will only contain
items up-to the last element, ie the length of the resultant-sequence
will be shorter than j - i, where j > len( sequence ).
# Proof (which concurs with the OP's observations)
# playing with a tuple's indexes/indices
>>> sequence = 1,2,3
>>> sequence[ 1 ]
2
# notice the result's type!
>>> sequence[ 9 ]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: tuple index out of range
# the above index is plainly 'beyond' len( sequence )
# do you know about negative indexes/indices?
>>> sequence[ -1 ]
3
>>> sequence[ -9 ]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: tuple index out of range
# again this index is 'beyond' the first element of the sequence
# let's play with some slicing;
>>> sequence[ 0:3 ]
(1, 2, 3)
>>> [ 1, 2, 3 ][ 0:3 ]
[1, 2, 3]
# same applies to lists (and strings, etc)
# notice the types!
>>> sequence[ 1:1 ]
()
>>> sequence[ 1:2 ]
(2,)
>>> sequence[ -1:2 ]
()
>>> sequence[ -1:-2 ]
()
>>> sequence[ -1:-2:-1 ]
(3,)
>>> sequence[ -1:-3:-1 ]
(3, 2)
# OK, what happens when parameters point to non-existent indexes?
>>> sequence[ 1:9 ]
(2, 3)
>>> sequence[ 1:-9 ]
()
>>> sequence[ -1:-9:-1 ]
(3, 2, 1)
>>> sequence[ -9:-1:-1 ]
()
# yes, they are parameters and not strictly indexes/indices!
https://docs.python.org/3/reference/datamodel.html?highlight=slicing#the-standard-type-hierarchy
for "sequences" and "slice objects"
Note that a Python set is "collection" but not a "sequence". Which means
that neither indexing nor slicing (per above) will work on a set. We can
ask if a particular value appears in a set ("contains") but cannot ask
for the n-th element. To be able to index or slice it, a sequence must
offer a __getitem__() method - tuple, list, and string do; but set does
not. (check for yourself: help( set ) )
https://docs.python.org/3/library/collections.abc.html?highlight=collection
--
Regards,
=dn
More information about the Python-list
mailing list