Для вашего нового редактируемого вопроса:
.*?
может соответствовать любому числу символов, включая ноль. Итак, что он делает, он соответствует нулевым символам в каждой позиции в строке: перед «a», между «a» и «b» и т. Д. Он заменяет каждое из этих совпадений нулевой ширины дефисом, давая результат вы видите.
Регулярное выражение не пытается сопоставлять каждый символ по одному; он пытается совместить в каждой позиции в строке. Ваше регулярное выражение позволяет ему соответствовать нулевым символам. Поэтому он соответствует нулю в каждой позиции и переходит к следующему. Кажется, вы думаете, что в строке, такой как «abc», есть одна позиция перед «b», одна позиция «внутри» «b» и одна позиция после «b», но нет позиции «внутри» «индивидуальный характер. Если он соответствует нулевым символам, начинающимся до «b», следующая вещь, которую он пытается, должна начинаться после «b». Нет никакого способа заставить регулярное выражение совместить семь раз в трехсимвольной строке, потому что есть только четыре позиции, которые можно сопоставить.
Структура данных массива numpy реализована в C. Размеры массива хранятся в структуре C. Они не хранятся в корте Python. Поэтому каждый раз, когда вы читаете атрибут shape
, создается новый кортеж Python для новых целочисленных объектов Python. Когда вы используете arr.shape[0]
, этот кортеж затем индексируется, чтобы вытащить первый элемент, что добавит немного дополнительных накладных расходов. len(arr)
должен только создать целое число Python.
Вы можете легко убедиться, что arr.shape
создает новый кортеж каждый раз, когда он читается:
In [126]: arr = np.random.randint(1, 11, size=(3, 4, 5))
In [127]: s1 = arr.shape
In [128]: id(s1)
Out[128]: 4916019848
In [129]: s2 = arr.shape
In [130]: id(s2)
Out[130]: 4909905024
s1
и s2
имеют разные id
s; они представляют собой разные кортежи.