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?
Asked By: yamm

||

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.

Answered By: deets

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.

Answered By: interjay

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.

Answered By: Mazdak

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.

Answered By: Emilio M Bumachar

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]])
Answered By: Shital Shah
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.