Python List Slicing с None как аргумент

Через пробную версию и ошибку я узнал, что

my_list = range(10)
my_list[:None] == my_list[:]

Я использую это для наборов запросов django, поэтому я могу определить размер или взять все:

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]
  • Хорошо ли использовать None при нарезке?
  • В этом случае могут возникнуть проблемы с этим методом?

Ответы

Ответ 1

Да, отлично использовать None, так как его поведение определяется документацией:

Срез s от я до j определяется как последовательность элементов с индексом k, такая что я <= k < к. Если я или j больше len (s), используйте len (s). Если я опущено или None, используйте 0. Если j опущено или None, используйте len (s). Если я больше или равно j, срез пуст.

Использование None для одного из параметров среза - это то же самое, что и его удаление.

Ответ 2

Твой путь прекрасен, но я бы предпочел:

some_queryset[:length] if length else some_queryset

или

some_queryset[:length] if length else some_queryset[:]

которые читаются с меньшим знанием того, как нарезка обрабатывает эти особые случаи.

Ответ 3

Это должно быть безопасно. В Python something[<sliceexpr>] эквивалентно something[slice(...)], а документация для типа slice явно указывает, что аргументы для остановки и по умолчанию по умолчанию - None.

Ответ 4

Нет никакой разницы между использованием None или использованием пустого среза, такого как [:], но использование None полезно, когда вы хотите использовать его в понимании списка или использовать его при условии среза, например:

>>> [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]]

Из комментария в CPython source о функции среза:

Возвращает новый объект среза с заданными значениями. Начало, stop и step используются как значения атрибутов объекта среза с одинаковыми именами. Любое из значений может быть NULL, в этом случае None будет использоваться для соответствующего атрибута. Возвращает NULL, если новый объект не мог выделяться.