Python List Slicing with None as argument
Question:
Via trial and error I found out that
my_list = range(10)
my_list[:None] == my_list[:]
I use this for django query sets so I can define a size or take all:
some_queryset[:length if length else None]
# @IanAuld
some_queryset[:length or None]
# @Bakuriu
# length works for all numbers and None if you want all elements
# does not work with False of any other False values
some_queryset[:length]
- Is this good practice to use
None
while slicing?
- Can problems occur with this method in any case?
Answers:
It should be safe. In Python, something[<sliceexpr>]
is equivalent to something[slice(...)]
, and the documentation for the slice
type clearly indicates that the arguments for stop and step default to None
.
Yes, it is fine to use None
, as its behavior is specified by the documentation:
The slice of s from i to j is defined as the sequence of items with index k such that i <= k < j. If i or j is greater than len(s), use len(s). If i is omitted or None, use 0. If j is omitted or None, use len(s). If i is greater than or equal to j, the slice is empty.
Using None
for one of the slice parameters is the same as omitting it.
There is no difference between using None
or using empty slicing like [:]
but using None
is useful when you want to use it within a list comprehension or use it under a condition for slicing, for example :
>>> [my_list[:length if length%2==0 else None] for length in [1,2,3]]
[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 1], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]
From a comment in CPython
source about slice function :
Return a new slice object with the given values. The start,
stop, and step parameters are used as the values of the slice object attributes of the same names. Any of the values may be
NULL, in which case the None
will be used for the corresponding attribute. Return NULL if the new object could not
be allocated.
Your way is fine, but I would prefer :
some_queryset[:length] if length else some_queryset
or
some_queryset[:length] if length else some_queryset[:]
which are readable with less knowledge of how slicing treats these special cases.
As answer by @kasravnd describes, using None is same as not specifying anything in slice operator (i.e. it means all) but it is useful feature in case you want to conditionally specify an index or all.
However, there is also another use of None but it applies only to Numpy and Pytorch: You can use None in slice operator to add additional dimension to array.
import numpy as np
abc=np.array([1,2,3])
print(abc[:,None])
This prints:
array([[1],
[2],
[3]])
Via trial and error I found out that
my_list = range(10)
my_list[:None] == my_list[:]
I use this for django query sets so I can define a size or take all:
some_queryset[:length if length else None]
# @IanAuld
some_queryset[:length or None]
# @Bakuriu
# length works for all numbers and None if you want all elements
# does not work with False of any other False values
some_queryset[:length]
- Is this good practice to use
None
while slicing? - Can problems occur with this method in any case?
It should be safe. In Python, something[<sliceexpr>]
is equivalent to something[slice(...)]
, and the documentation for the slice
type clearly indicates that the arguments for stop and step default to None
.
Yes, it is fine to use None
, as its behavior is specified by the documentation:
The slice of s from i to j is defined as the sequence of items with index k such that i <= k < j. If i or j is greater than len(s), use len(s). If i is omitted or None, use 0. If j is omitted or None, use len(s). If i is greater than or equal to j, the slice is empty.
Using None
for one of the slice parameters is the same as omitting it.
There is no difference between using None
or using empty slicing like [:]
but using None
is useful when you want to use it within a list comprehension or use it under a condition for slicing, for example :
>>> [my_list[:length if length%2==0 else None] for length in [1,2,3]]
[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 1], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]
From a comment in CPython
source about slice function :
Return a new slice object with the given values. The start,
stop, and step parameters are used as the values of the slice object attributes of the same names. Any of the values may be
NULL, in which case theNone
will be used for the corresponding attribute. Return NULL if the new object could not
be allocated.
Your way is fine, but I would prefer :
some_queryset[:length] if length else some_queryset
or
some_queryset[:length] if length else some_queryset[:]
which are readable with less knowledge of how slicing treats these special cases.
As answer by @kasravnd describes, using None is same as not specifying anything in slice operator (i.e. it means all) but it is useful feature in case you want to conditionally specify an index or all.
However, there is also another use of None but it applies only to Numpy and Pytorch: You can use None in slice operator to add additional dimension to array.
import numpy as np
abc=np.array([1,2,3])
print(abc[:,None])
This prints:
array([[1],
[2],
[3]])