Числа и строки
Долг за прошлую лекцию:
- документирование функций
- лямбда-функции (функции-выражения)
- Лайф-хак вида print(*последовательность)
- ⇒ максимальная глубина рекурсии
- ⇒ логарифмический критерий уместности рекурсии
Числа
Больше математики!
Датасатанизм: Pandas, TensorFlow, scikit-learn
Псевдослучайные числа
random (и secrets, а также os.getrandom)
random()/randrange()
Управление датчиком: seed(), getstate()
- Воспроизводимость псевдослучайной последовательности
1 >>> seed(100500) 2 >>> [randrange(10) for i in range(20)] 3 [8, 6, 2, 0, 2, 3, 8, 8, 8, 1, 7, 8, 1, 3, 4, 0, 3, 4, 4, 0] 4 >>> [randrange(10) for i in range(20)] 5 [5, 7, 4, 3, 0, 9, 4, 3, 2, 2, 1, 8, 4, 3, 2, 5, 5, 2, 5, 2] 6 >>> [randrange(10) for i in range(20)] 7 [6, 6, 6, 4, 9, 6, 9, 0, 6, 4, 4, 6, 1, 0, 8, 3, 7, 8, 6, 7] 8 >>> seed(100500) 9 >>> [randrange(10) for i in range(20)] 10 [8, 6, 2, 0, 2, 3, 8, 8, 8, 1, 7, 8, 1, 3, 4, 0, 3, 4, 4, 0] 11 >>> [randrange(10) for i in range(20)] 12 [5, 7, 4, 3, 0, 9, 4, 3, 2, 2, 1, 8, 4, 3, 2, 5, 5, 2, 5, 2] 13 >>> [randrange(10) for i in range(20)] 14 [6, 6, 6, 4, 9, 6, 9, 0, 6, 4, 4, 6, 1, 0, 8, 3, 7, 8, 6, 7] 15 >>> [randrange(10) for i in range(20)] 16 [0, 2, 3, 6, 2, 1, 6, 3, 5, 8, 5, 6, 5, 7, 3, 1, 0, 6, 3, 5] 17
choice()/shuffle() простые
sample() (без повторений)
choices() похитрее
1 >>> choices(range(10,100), [1]*90, k=20) # равные веса 2 [94, 50, 52, 78, 38, 95, 22, 18, 24, 32, 25, 92, 48, 42, 62, 49, 97, 95, 55, 59] 3 >>> choices(range(10,100), range(90,0,-1), k=20) # малые числа тяжелее 4 [20, 18, 45, 85, 45, 41, 30, 72, 58, 18, 20, 43, 20, 10, 44, 21, 22, 64, 25, 39] 5 >>> choices(range(10,100), cum_weights=range(90), k=20) # равные кумулятивные веса 6 [28, 94, 61, 21, 48, 43, 13, 53, 49, 31, 94, 99, 84, 39, 13, 52, 43, 11, 98, 79] 7 >>> choices(range(10), cum_weights=[c for c in range(15) if c%3], k=20) 8 [6, 2, 4, 2, 8, 6, 8, 3, 6, 8, 9, 8, 8, 1, 6, 2, 2, 0, 4, 9] 9 >>> from collections import Counter as C 10 >>> S = choices(range(10), cum_weights=[c for c in range(15) if c%3], k=1000) 11 >>> Counter(S) # 2,4,6,8 — в два раза чаще остальных 12 Counter({6: 165, 4: 152, 2: 145, 8: 127, 9: 83, 0: 70, 7: 69, 1: 68, 3: 66, 5: 55}) 13 >>> choices("qwe", (1,2,3), k=16) 14 ['e', 'q', 'e', 'e', 'w', 'e', 'w', 'q', 'e', 'e', 'w', 'e', 'q', 'e', 'e', 'q'] 15 >>> for i in range(7): 16 ... print(C(choices("qwe", (1,2,3), k=16))) 17 Counter({'e': 10, 'w': 5, 'q': 1}) 18 Counter({'e': 9, 'w': 4, 'q': 3}) 19 Counter({'e': 6, 'w': 6, 'q': 4}) 20 Counter({'e': 9, 'w': 5, 'q': 2}) 21 Counter({'w': 6, 'q': 5, 'e': 5}) 22 Counter({'w': 9, 'e': 7}) 23 Counter({'e': 8, 'q': 4, 'w': 4}) 24 >>> for i in range(7): 25 ... print(C(choices("qwe", cum_weights=(1,2,3), k=16))) 26 Counter({'e': 8, 'w': 6, 'q': 2}) 27 Counter({'w': 7, 'q': 6, 'e': 3}) 28 Counter({'q': 6, 'w': 5, 'e': 5}) 29 Counter({'w': 10, 'q': 4, 'e': 2}) 30 Counter({'w': 8, 'e': 5, 'q': 3}) 31 Counter({'q': 8, 'e': 6, 'w': 2}) 32 Counter({'q': 8, 'w': 4, 'e': 4}) 33
Строки
- Внутреннее unicode-представление
- Ещё более внутреннее — переход от ASCII в Unicode и обратно, но нам этого не видно!
- На самом деле видно:
1 >>> import sys 2 >>> a ="qwerty" 3 >>> print(len(a), sys.getsizeof(a)) 4 6 55 5 >>> b = a + "!" 6 >>> print(len(b), sys.getsizeof(b)) 7 7 56 8 >>> b = a + "SDF" 9 >>> print(len(b), sys.getsizeof(b)) 10 9 58 11 >>> b = a + "ы" 12 >>> print(len(b), sys.getsizeof(b)) 13 7 88 14 >>> b = a + "ыы" 15 >>> print(len(b), sys.getsizeof(b)) 16 8 90 17
4 способа задания строк («'», «"», «'''» и «"""»)
- строки как последовательности: особенности:
Строка — это последовательность строк
a[5] === a[5:6] (так ли это? )
- Поиск подстроки: "asd" in "qwasdgfh"
линейный Алгоритм Кнута — Морриса — Пратта
Строковые методы
endswith(), startswith(),
find(), index(), count(),
isalnum(), isalpha(), isdecimal(), isdigit(), isidentifier(), islower(), isnumeric(), isprintable(), isspace(), istitle(), isupper(),
center(), rjust(), ljust(),
lower(), upper(), swapcase(), title(), capitalize(), casefold(),
replace(),
strip(), expandtabs(), removeprefix(), removesuffix()
zfill(),
rfind(), rindex(), rpartition(), rsplit(), rstrip(), lstrip(),
split() и join()
split(), splitlines(), join()
Форматные строки
Общий формат: f"…{выражение}…"
- Типизация и форматирование по ширине
Плюшки (например, f"{выражение=}" 3.8+)
Метод .format() (например, в случае, когда строка прдварительно формируется)
Lecacy "строка-с-%" % последовательность (похожая на Си)
NEW Python3.12: Syntactic formalization of f-strings
Можно попробовать тут: a="QQQ"; print(f"{a + "!"}")
Спецсимволы и необработанные строки
Зачем нужны спецсимволы
\b, \t, \b, \r; \xчисло, … остальное
r"..."
Д/З
Во всех домашних заданиях нашего курса используются только стандартные модули Python.
Прочитать и прощёлкать про строки в учебнике, в документации, а также про форматирование строк в учебнике и в документации.
EJudge: PatternFind 'Поиск простого шаблона в строке'
Ввести строку, содержащую произвольные символы (кроме символа «@»). Затем ввести строку-шаблон, которая может содержать символы '@'. Проверить, содержится ли в исходной строке подстрока, совпадающая со строкой-шаблоном везде, кроме символов '@'; на месте '@' в исходной строке должен стоять ровно один произвольный символ. Вывести наименьшую позицию в строке, с которой начинается эта подстрока, или '-1', если её там нет. Использовать регулярные выражения нельзя! ☺
lorem ipsum, quia dolor sit, amet, consectetur dolor @it,@@met
18
EJudge: MultTable 'Таблица умножения'
Ввести два натуральных числа через запятую: N и M. Вывести таблицу умножения от 1 до N включительно в формате, представленном ниже, разделяя колонки, если они есть, тремя символами «.|.» («.*.» и «.=.» также занимают по три символа). Количество столбцов в выводе должно быть наибольшим, но общая ширина строки не должна превышать M (предполагается, что M достаточно велико, чтобы вместить один столбец). Ширина колонок под сомножители и произведения должна соответствовать максимальной ширине соответствующего значения (даже если в данной колонке данного столбца эта ширина не достигается, см. пример). Таким образом все столбцы должны быть одинаковой ширины. Разделители вида "===…===" должны быть ширины M.
11, 62
============================================================== .1.*.1..=.1...|..2.*.1..=.2...|..3.*.1..=.3...|..4.*.1..=.4.. .1.*.2..=.2...|..2.*.2..=.4...|..3.*.2..=.6...|..4.*.2..=.8.. .1.*.3..=.3...|..2.*.3..=.6...|..3.*.3..=.9...|..4.*.3..=.12. .1.*.4..=.4...|..2.*.4..=.8...|..3.*.4..=.12..|..4.*.4..=.16. .1.*.5..=.5...|..2.*.5..=.10..|..3.*.5..=.15..|..4.*.5..=.20. .1.*.6..=.6...|..2.*.6..=.12..|..3.*.6..=.18..|..4.*.6..=.24. .1.*.7..=.7...|..2.*.7..=.14..|..3.*.7..=.21..|..4.*.7..=.28. .1.*.8..=.8...|..2.*.8..=.16..|..3.*.8..=.24..|..4.*.8..=.32. .1.*.9..=.9...|..2.*.9..=.18..|..3.*.9..=.27..|..4.*.9..=.36. .1.*.10.=.10..|..2.*.10.=.20..|..3.*.10.=.30..|..4.*.10.=.40. .1.*.11.=.11..|..2.*.11.=.22..|..3.*.11.=.33..|..4.*.11.=.44. ============================================================== .5.*.1..=.5...|..6.*.1..=.6...|..7.*.1..=.7...|..8.*.1..=.8.. .5.*.2..=.10..|..6.*.2..=.12..|..7.*.2..=.14..|..8.*.2..=.16. .5.*.3..=.15..|..6.*.3..=.18..|..7.*.3..=.21..|..8.*.3..=.24. .5.*.4..=.20..|..6.*.4..=.24..|..7.*.4..=.28..|..8.*.4..=.32. .5.*.5..=.25..|..6.*.5..=.30..|..7.*.5..=.35..|..8.*.5..=.40. .5.*.6..=.30..|..6.*.6..=.36..|..7.*.6..=.42..|..8.*.6..=.48. .5.*.7..=.35..|..6.*.7..=.42..|..7.*.7..=.49..|..8.*.7..=.56. .5.*.8..=.40..|..6.*.8..=.48..|..7.*.8..=.56..|..8.*.8..=.64. .5.*.9..=.45..|..6.*.9..=.54..|..7.*.9..=.63..|..8.*.9..=.72. .5.*.10.=.50..|..6.*.10.=.60..|..7.*.10.=.70..|..8.*.10.=.80. .5.*.11.=.55..|..6.*.11.=.66..|..7.*.11.=.77..|..8.*.11.=.88. ============================================================== .9.*.1..=.9...|.10.*.1..=.10..|.11.*.1..=.11. .9.*.2..=.18..|.10.*.2..=.20..|.11.*.2..=.22. .9.*.3..=.27..|.10.*.3..=.30..|.11.*.3..=.33. .9.*.4..=.36..|.10.*.4..=.40..|.11.*.4..=.44. .9.*.5..=.45..|.10.*.5..=.50..|.11.*.5..=.55. .9.*.6..=.54..|.10.*.6..=.60..|.11.*.6..=.66. .9.*.7..=.63..|.10.*.7..=.70..|.11.*.7..=.77. .9.*.8..=.72..|.10.*.8..=.80..|.11.*.8..=.88. .9.*.9..=.81..|.10.*.9..=.90..|.11.*.9..=.99. .9.*.10.=.90..|.10.*.10.=.100.|.11.*.10.=.110 .9.*.11.=.99..|.10.*.11.=.110.|.11.*.11.=.121 ==============================================================
EJudge: AlmostRandom 'Почти случайное'
Написать функцию divrandom(a, b, s, p), принимающую четыре целых ненулевых параметра. Функция должна возвращать случайно выбранное целое число, не кратное p, из диапазона от a до b (включительно; таким образом диапазоны a…b и b…a одинаковы и допустимы) с шагом s. Если такое число выбрать невозможно, функция возвращает 0.
1 print(divrandom(10, 21, 5, 2))
15
EJudge: TriangleSquare 'Площадь треугольника'
Ввести через запятую шесть чисел: x1, y1, x2, y2, x3, y3 и вывести точное значение площади треугольника (x1, y1), (x2, y2), (x3, y3).
1.1, 1, 6, 4, 8, 2
7.9