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, если новый объект не мог выделяться.