<jupyter_start><jupyter_text>Навигация* [Типы данных](Типы-данных,-логические-операции-и-условные-операторы)    * [Целочисленные (integer)]()        * [Операции с целыми числами](Операции-с-целыми-числами.)            * [Основные арифметические операции](Основные-арифметические-операции)    * [С плавающей точкой (float)]()    * [Строковые (string)]()    * [Логические (boolean)]()* [Ввод и вывод данных](Ввод-и-вывод-данных)  Ввод и вывод данных[↑ вернуться к оглавлению](Навигация)Данные в питоне можно вводить при помощи **input()**, а выводить при помощи **print()**.Важно! **input()** всегда возвращает строку (**str**, об этом ниже).<jupyter_code>a = input('введи значение a: ') # если ничего не указать в скобках, то будет просто строка ввода
print('а =', a)
print(a + a + a + ' слонов топнули ' + a + ' раз ')
print(a, a, a, 'слонов топнули', a, 'раз')<jupyter_output>5 5 5 слонов топнули 5 раз<jupyter_text>Перенести текст на новую строку можно при помощи **\n**<jupyter_code>print(a + a + '\n' + a + ' слонов топнули \n' + a + ' \nраз ')<jupyter_output>55
5 слонов топнули 
5 
раз<jupyter_text>___ Операции с целыми числами. [↑ вернуться к оглавлению](Навигация) Основные арифметические операции[↑ вернуться к оглавлению](Навигация)<jupyter_code># Всё стандартно + - * /

a = 11111 * 1111111
print('a =', a, 'тип', type(a))

b = 11111 + 1111111
print('b =', b, 'тип', type(b))

c = 11111 - 1111111
print('c =', c, 'тип', type(c))

d = 11111 / 1111111
print('d =', d, 'тип', type(d))<jupyter_output>a = 12345554321 тип <class 'int'>
b = 1122222 тип <class 'int'>
c = -1100000 тип <class 'int'>
d = 0.0099999009999901 тип <class 'float'><jupyter_text>Несколько слов о делении[↑ вернуться к оглавлению](Навигация)<jupyter_code># Целочисленное деление выполняется с помощью //, получим int 
a = 239 // 10
print(a, type(a))
# Вещественное деление выполняется с помощью /, получим float
a = 100 / 10
print(a, type(a))
# Целочисленный остаток от деления выполняется с помощью %, получим int
a = 239 % 10
print(a, type(a))<jupyter_output>9 <class 'int'><jupyter_text>Возведение в степень[↑ вернуться к оглавлению](Навигация)<jupyter_code># Возведение в степень выполняется с помощью **
a = 5**4
print(a, type(a))<jupyter_output>625 <class 'int'><jupyter_text>Извлечение квадратного корня[↑ вернуться к оглавлению](Навигация)<jupyter_code>a = pow(9, .5)
b = 9**.5

import math
c = math.sqrt(9)

print('медленно, но через встроенную функцию \na =', 
      a, 
      '\nбыстрее, но нативно \nb =', 
      b, 
      '\nсамый быстрый способ, но придётся импортировать math \nc =', 
      c)<jupyter_output>медленно, но через встроенную функцию 
a = 3.0 
быстрее, но нативно 
b = 3.0 
самый быстрый способ, но придётся импортировать math 
c = 3.0<jupyter_text>Запись чисел, типа 5Е-2[↑ вернуться к оглавлению](Навигация)<jupyter_code>a = 5e-1 # 5 умножить на 10 в степени -1
b = 5e+3 # 5 умножить на 10 в степени 3
c = 1.2345e-3
print('a =', a, 'тип' ,type(a), '\nb =', b, 'тип',type(b), '\nс =', c, 'тип',type(c))<jupyter_output>a = 0.5 тип <class 'float'> 
b = 5000.0 тип <class 'float'> 
с = 0.0012345 тип <class 'float'><jupyter_text>Операторы приращения[↑ вернуться к оглавлению](Навигация)В питоне существуют такие операторы, как:* += - прибавить к числу (аналог инкремента);* -= - вычесть из числа;* \*= - умножить на;* /= - вещественное деление;* //= - целочисленное деление;* %= - остаток от деления;* \*\*= возведение в степень.Примеры:<jupyter_code>a = 5
print('начальное число а =', a)

a += 1 # а + 1 (a = 5)
print('a += 1, ровняется -', a)

a -= 1 # a - 1 (a = 6)
print('a -= 1, ровняется -', a)

a *= 10 # a * 10 (a = 5)
print('a *= 10, ровняется -', a)

a /= 2 # a / 2 (a = 50)
print('a /= 2, ровняется -', a)

a //= 5 # a // 5 (a = 25, и так как мы умножаем int на float результат автоматически будет float)
print('a //= 5, ровняется -', a)

a %= 2 # отстаток от деления на 2 (a = 5)
print('a %= 2, ровняется -', a)

a **=2 # a в степени 2 (a = 1)
print('a *= 2, ровняется -', a)<jupyter_output>начальное число а = 5
a += 1, ровняется - 6
a -= 1, ровняется - 5
a *= 10, ровняется - 50
a /= 2, ровняется - 25.0
a //= 5, ровняется - 5.0
a %= 2, ровняется - 1.0
a *= 2, ровняется - 1.0<jupyter_text>___  Типы данных, логические операции и условные операторы[↑ вернуться к оглавлению](Навигация)В python все переменные это объекты, каждый объект должен принадлежать к определенному типу. Есть 4 основных типа:* целые числа - **int**;* вещественные (с плавающей точкой) - **float**;* логические - **bool**;* строковые - **str**.Эти типы данных являются *неизменяемыми*. Т.е. это означает, что к переменной **int** мы не можем просто так прибавить значение **str** переменной, для этого требуется создать новый объект, или же, если это возможно и оправдано -- использовать приведение. Например:<jupyter_code>a = 5
print('a =', a)

b = '5'
print('b =', b)<jupyter_output>a = 5
b = 5<jupyter_text>Вывод двух переменных выглядит одинаково, но на самом деле они имеют разный тип:<jupyter_code>print('тип переменной a -', type(a), '\nтип переменной b -', type(b))<jupyter_output>тип переменной a - <class 'int'> 
тип переменной b - <class 'str'><jupyter_text>Попробуем сложить эти переменные:<jupyter_code>c = a + b
print(c)<jupyter_output><empty_output><jupyter_text>Мы получили ошибку, так как нельзя сложить **int** и **str**. Для того, что бы сложить эти переменные, нужно привести **b** к числовому типу, для этого перед переменной **b** укажем тип, к которому мы хотим её привести:<jupyter_code>c = a + int(b)
print('c =', c, '\nтип переменной с -', type(c))<jupyter_output>c = 10 
тип переменной с - <class 'int'><jupyter_text>Немного про bool**bool** -- логический тип данных и может быть либо **True** (равен логической 1) либо **False** (равен логическому 0)<jupyter_code>a = False
print(a, type(a))

a = True
print(a, type(a))

a = False + True
print(a, type(a))

a = True + True
print(a, type(a))

a = False + False
print(a, type(a))<jupyter_output>False <class 'bool'>
True <class 'bool'>
1 <class 'int'>
2 <class 'int'>
0 <class 'int'><jupyter_text>Логические операцииОбъявим переменные и присвоим им значение<jupyter_code>a = True
b = True
c = False
d = False<jupyter_output><empty_output><jupyter_text>операция -- логическое **ИЛИ**результат равен **False** только в том случае, если обе переменных **False**, в остальных случаях **True**<jupyter_code>print(a or b, a or c, c or d)<jupyter_output>True True False<jupyter_text>операция - логическое **И**результат равен **True** только в том случае, если обе переменных **True**, в остальных случаях **False**<jupyter_code>print(a and b, a and c, c and d)<jupyter_output>True False False<jupyter_text>операция -- логическое **НЕ**проще говоря -- инвертирование<jupyter_code>print(not a, not b, not c, not d)<jupyter_output>False False True True<jupyter_text>Так же необходимо знать о приоритете операций, объясню на примере аналогий из математики:* **not** - это знак минуса (-) или просто запомнить, что **not** меняет значение на противоположное* **and** - это умножение (\*)* **or** - это сложение (+)Следовательно приоритет следующий: **not** > **and** > **or**Для наглядности, если взять задачу с расставлением приоритетов: a and b or not a and not b, решение будет таким:<jupyter_code>result = (a and b or not a and not b) # мистер Py сам расставит приоритеты и даст ответ False
print('result =', result)

result_new = ((a and b) or ((not a) and (not b))) # если все верно -- результат не должен измениться
print('result_new =', result_new)<jupyter_output>result = False
result_new = False<jupyter_text>Логические операторы и условные конструкцииЛогические операторы используются для сравнения и их результатом всегда будет bool.Существуют следующие операторы: ****, **>=**, **==**, **!=**Стандартные условные конструкции записываются в питоне как:**if** :**else**:Например:<jupyter_code>a = True
b = False
c = False

if a == True:
    print(not a) # выполнится это
else:
    print(a or b)
if 2 * 2 == 4:
    print('Ауф')
else:
    print('Мех')<jupyter_output>Ауф<jupyter_text>**if**`ы можно вкладывать 1 в другой последовательно проверяя условия:<jupyter_code>if a == True:
    if b != True:
        print('Ауф') # выполнится это
    else:
        print('Уф-уф')
else:
    print('Не ауф')<jupyter_output>Ауф<jupyter_text>В условии можно проверять несколько... условий, к примеру, если совпало хотя бы 1 из условий, то выведется *Ауф*.<jupyter_code>if a == True or b != True: # выполнится это
    print('Ауф')
else:
    print('Не ауф')<jupyter_output>Ауф<jupyter_text>Если требуется проверить выполнение всех условий строго, то конструкция будет следующей:<jupyter_code>if a == True and b != True: # выполнится это
    print('Ауф')
else:
    print('Не ауф')<jupyter_output>Ауф<jupyter_text>Можно так же использовать **elif** (**else if**) что бы не городить кучу **if**`ов подряд, правильнее будет так:<jupyter_code>if 2 + 2 == 5:
    print('о_О')
elif 2 + 2 == 4:
    print('=_=')
else:
    print('*_*')<jupyter_output>=_=<jupyter_text>\* **else** *необязательный блок, если не предусматривается алтернативное действие, в случае несовпадения условия, его можно не указывать.*  Касаемо конструкций **switch-case**Как вообще устроена конструкция **switch** **case** **break** в общем случае:* Компилятор генерирует таблицу перехода для оператора case switch.* Переменная/выражение переключателя оценивается один раз.* Оператор switch ищет оцененную переменную/выражение в таблице переходов и непосредственно решает, какой блок кода выполнить.* Если совпадение не найдено, код выполняется по умолчанию, если он был указан.Так вот, в Python нет такой реализации нативно, её можно реализовать самому через словари, но словари потрогаем позже. В двух словах -- реализация будет через запрос на возврат значения из словаря по ключу (**dictName.get**). Не в двух словах -- [можно почитать вот здесь большую пасту](https://ru.stackoverflow.com/a/460208).  Строки **str** и операции над ними.<jupyter_code>a = 'строка'
print(a)

b = "ничем не отличающаяся от предыдущей строка"
print(b)

c = '"Текст в ковычках"'
print(c)

d = """Мультистрочный
текст
пишу где хочу
"""
print(d)<jupyter_output>строка
ничем не отличающаяся от предыдущей строка
"Текст в ковычках"
Мультистрочный
текст
пишу где хочу<jupyter_text>Строки можно сравнивать, складывать, умножать, узнавать её длину, найти наличие подстроки в строке и тд:<jupyter_code>a = 'Саня '
b = 'верни '
c = 'сотку'

print(a + b + c) # сложение строк (конкатенация)

print(a + b + c * 3) # умножение строки "c" на три

print('Длина строки "Саня верни сотку" =', len(a + b + c))<jupyter_output>Саня верни сотку
Саня верни соткусоткусотку
Длина строки "Саня верни сотку" = 16<jupyter_text>Некоторые методы, которые можно использовать с строками:* **isalpha()**: возвращает **True**, если строка состоит только из алфавитных символов* **islower()**: возвращает **True**, если строка состоит только из символов в нижнем регистре* **isupper()**: возвращает **True**, если все символы строки в верхнем регистре* **isdigit():** возвращает **True**, если все символы строки - цифры* **isnumeric():** возвращает **True**, если строка представляет собой число* **startswith(** *проверяемая подстрока* **)**: возвращает **True**, если строка начинается с проверяемой подстроки* **endswith(** *проверяемая подстрока* **)**: возвращает **True**, если строка заканчивается на проверяемую подстроку* **lower()**: переводит строку в нижний регистр* **upper()**: переводит строку в вехний регистр* **title()**: начальные символы всех слов в строке переводятся в верхний регистр* **capitalize()**: переводит в верхний регистр первую букву только самого первого слова строки* **lstrip()**: удаляет начальные пробелы из строки* **rstrip()**: удаляет конечные пробелы из строки* **strip()**: удаляет начальные и конечные пробелы из строки* **ljust(*width*)**: если длина строки меньше параметра *width*, то справа от строки добавляются пробелы, чтобы дополнить значение *width*, а сама строка выравнивается по левому краю* **rjust(*width*)**: если длина строки меньше параметра *width*, то слева от строки добавляются пробелы, чтобы дополнить значение *width*, а сама строка выравнивается по правому краю* **center(*width*)**: если длина строки меньше параметра *width*, то слева и справа от строки равномерно добавляются пробелы, чтобы дополнить значение *width*, а сама строка выравнивается по центру* **find(*проверяемая строка*[, *start* [, *end*])**: возвращает индекс подстроки в строке. Если подстрока не найдена, возвращается число -1* **replace(*old*, *new[, num]*)**: заменяет в строке одну подстроку на другую* **split([delimeter[, num]])**: разбивает строку на подстроки в зависимости от разделителя* **join(*строки*)**: объединяет строки в одну строку, вставляя между ними определенный разделитель* **count('*символ*')**: выведет количество найденных символовПримеры некоторых конструкций:<jupyter_code>a = 'съешь еще немножко этих вкусных французских булочек'
b = 'и днём и ночью кот ученый... всё ходит по цепи... кругом'

print(a.upper())

print(a.lower())

print(a.islower(), a.isalpha()) # True False

print(a.startswith('съешь')) # True

print(a.endswith('кругом')) # False

print(b.find('ём')) # да, индекс 4 (напоминаю, отсчет с нуля)

splitted_text = b.split('...') # разделяем текст по знаку ...
print(len(splitted_text)) # узнаем длину массива, там будет 3 ячейки
print(splitted_text) # выведем весь массив
print(splitted_text[1]) # выводим текст из второй ячейки

print(b.replace('е', 'i')) # заменим все буквы е на i

print(b.count('и')) # сколько раз символ 'и' встречается в строке b<jupyter_output>СЪЕШЬ ЕЩЕ НЕМНОЖКО ЭТИХ ВКУСНЫХ ФРАНЦУЗСКИХ БУЛОЧЕК
съешь еще немножко этих вкусных французских булочек
True False
True
False
4
3
['и днём и ночью кот ученый', ' всё ходит по цепи', ' кругом']
 всё ходит по цепи
и днём и ночью кот учiный... всё ходит по цiпи... кругом
4<jupyter_text>Строка, по сути, как и в любом языке, это последовательный набор символов. Если набор последователен, значит его можно индексировать. Таким образом к символам строки можно обращаться по индексу, вот ряд интересных операций:<jupyter_code>string = 'гном гномыч'

print(string[3]) # вывести символ с индексом 3 (индексирование в массивах и листах ВСЕГДА с 0)
print(string[2:4]) # вывести символ в диапозоне индексов от 2 до 4, причем 2 включается, а 4 не включается
print(string[:4]) # вывести символы от начала до указанного индекса (4 не включается)
print(string[4:]) # вывесли символы начиная с индекса 4
print(string[-4:]) # при указании отрицательного индекса, отсчет идет от конца строки (вывод не инвертируется)
print(string[1:-1]) # вывести от 1 индекса до -1 (1 индекс от конца)
print(string[1:-1:2]) # вывести от 1 до -1 с шагом в 2 (string(start_index:stop_index:step_lenght))
print(string[::-1]) # инвертировать строку

# что бы было понятнее с индексированием
# в вывод включается левая граница, правая граница не включается
# т.е. при выводе от [1:4] выведется строка с индекса 1 по индекс 3<jupyter_output>м
ом
гном
 гномыч
омыч
ном гномы
нмгоы
чымонг монг<jupyter_text>Циклы  while**While** -- цикл, который выполняется до тех пор, пока его условие true<jupyter_code>a = 5
i = 0
while a > 0:
    i += 1
    print('a =', a, 'итераций: ', i)
    a -= 1
a = 5
i = 0
while a > 0:
    i += 1
    if a % 2 == 0: # выведем только четные числа
        print('a =', a, 'итераций: ', i)
    a -= 1
a = 5
i = 0
flag = True

while flag: # пока flag = True цикл будет выполняться
    i += 1
    if a % 2 == 0: # выведем только четные числа
        print('a =', a, 'итераций: ', i)
    a -= 1
    if a == 0: # как только получили а = 0, устанавливаем flag в False
        flag = False
        print('Завершение цикла')<jupyter_output>a = 4 итераций:  2
a = 2 итераций:  4
Завершение цикла<jupyter_text>break и continue**While** можно прервать **break** или же пропустить выполнение итерации **continue**<jupyter_code>a = 5
i = 0
flag = True

while flag: # пока flag = True цикл будет выполняться ( в этом примере flag всегда True, т.е. цикл вечный)
    i += 1
    if a % 2 == 0: # выведем только четные числа
        print('a =', a, 'итераций: ', i)
    a -= 1
    if a == 0: # как только получили а = 0, устанавливаем flag в False
        print('прерываем цикл')
        break
a = 5
i = 0
flag = True

while flag: # пока flag = True цикл будет выполняться ( в этом примере flag всегда True, т.е. цикл вечный)
    i += 1
    a -= 1
    print('в начале итерации а =', a)
    if a % 2 != 0: # каждый раз, когда у нас нечетное число, мы пропускаем остальное выполнение кода
        print('пропускаем дальнейший код')
        continue
    if a == 0: # как только получили а = 0, устанавливаем flag в False
        print('прерываем цикл')
        break<jupyter_output>в начале итерации а = 4
в начале итерации а = 3
пропускаем дальнейший код
в начале итерации а = 2
в начале итерации а = 1
пропускаем дальнейший код
в начале итерации а = 0
прерываем цикл<jupyter_text>for **For** -- цикл, который будет выполняться по заданному условию. Так как в Python отсутствует цикл **foreach**, потому что конструкция цикла **for** гибкая, цикл **for** имеет конструкцию очень схожую с **foreach**.<jupyter_code>i = 0

for i in range(10):
    print(i)
array = [1, 4, 5, 60 , 32] # так задаётся лист

for i in array: # итеративно выведет весь лист
    print(i)
array = [1, 4, 5, 60 , 32], [12, 23, 45, 23 , 4] # так задаётся лист, который состоит из двух массивов

for i in array: # итеративно выведет весь лист
    print(i)
array = [1, 4, 5, 60 , 32], [12, 23, 45, 23 , 4] # так задаётся лист, который состоит из двух массивов

for i in array[1]: # итеративно выведет лист (найди 5 отличий)
    print(i)<jupyter_output>12
23
45
23
4<jupyter_text>Списки (list) В Python пошли еще на одно упрощение и отказались от массивов, оставив только списки, так как у массива есть ряд неудобных ограничений, вроде того, что длина его должна быть неизменной и тд. Очевидным приемуществом списков является то, что в их ячейках, по аналогии с массивами, можно хранить любой тип данных.Рассмотрим списки на примере:<jupyter_code>group = ['sovvy', 'covvy', 'borry'] # так задаётся список (лист)

# выведем из него элемент с индексом 1 и посмотрим на его тип 
print(group[1], type(group[1]))

# мы можем вывести все элементы листа при помощи цикла
for i in group:
    print(i)
    
# длина листа узнается как и длина строки
print(len(group)) # т.е. 3 ячейки<jupyter_output>covvy <class 'str'>
sovvy
covvy
borry
3<jupyter_text>Очевидно, что работа с листом очень похожа на работу с строками. При помощи тех же слайсов, которые мы использовали при выводе текста их строки, можно выводить элементы списка:<jupyter_code>print(group[1:2])
print(group[:2])
print(group[-1])
print(group[::-1])
# и так далее<jupyter_output>['covvy']
['sovvy', 'covvy']
borry
['borry', 'covvy', 'sovvy']<jupyter_text>Листы можно складывать между собой, в таком случае второй лист впишется в конец, после первого списка. Списки можно умножать на число и тд:<jupyter_code>member = ['Саня', 'Ваня', 'Маня']

group += member
print(group)

group *= 2
print(group)<jupyter_output>['sovvy', 'covvy', 'borry', 'Саня', 'Ваня', 'Маня']
['sovvy', 'covvy', 'borry', 'Саня', 'Ваня', 'Маня', 'sovvy', 'covvy', 'borry', 'Саня', 'Ваня', 'Маня']<jupyter_text>Ранее изученные типы данных **int**, **str**, **float**, **bool** -- являлись неизменяемыми (хз почему, так в справке написано, я проверял, у тебя тоже сейчас возникнет вопрос, это стоит просто запомнить, т.к. это спрашивают везде), но листы являются изменяемым типом данных, по индексу мы можем вписать новое значение:<jupyter_code>group[1] = 'worry' # запишем в ячейку с индексом 1 новое значение
print(group)<jupyter_output>['sovvy', 'worry', 'borry', 'Саня', 'Ваня', 'Маня', 'sovvy', 'covvy', 'borry', 'Саня', 'Ваня', 'Маня']<jupyter_text>В список можно добавлять элементы не просто прибавляя к нему другие списки, а просто при помощи метода **.append()**:<jupyter_code>group.append('Пётр')
print(group)<jupyter_output>['sovvy', 'worry', 'borry', 'Саня', 'Ваня', 'Маня', 'sovvy', 'covvy', 'borry', 'Саня', 'Ваня', 'Маня', 'Пётр']<jupyter_text>Тоже самое у нас происходит при прибавлении листа:<jupyter_code>group += ['Другой Пётр']
print(group)<jupyter_output>['sovvy', 'worry', 'borry', 'Саня', 'Ваня', 'Маня', 'sovvy', 'covvy', 'borry', 'Саня', 'Ваня', 'Маня', 'Пётр', 'Другой Пётр']<jupyter_text>Обрати внимание, если к листу прибавить строку, то так как строка является индексируемым набором символов, то мы добавим не 1 новое зачение в конец листа, а столько значений, сколько букв в строке:<jupyter_code>group += 'строка'
print(group)<jupyter_output>['sovvy', 'worry', 'borry', 'Саня', 'Ваня', 'Маня', 'sovvy', 'covvy', 'borry', 'Саня', 'Ваня', 'Маня', 'Пётр', 'Другой Пётр', 'с', 'т', 'р', 'о', 'к', 'а']<jupyter_text>Если нам требуется не просто добавить элемент дефолтно в конец, а вставить его на конкретную позицию, то используется метод **.insetr(index, element)**<jupyter_code>print(group)

group.insert(2, 'borry')
print(group)<jupyter_output>['sovvy', 'worry', 'borry', 'Саня', 'Ваня', 'Маня', 'sovvy', 'covvy', 'borry', 'Саня', 'Ваня', 'Маня', 'Пётр', 'Другой Пётр', 'с', 'т', 'р', 'о', 'к', 'а']
['sovvy', 'worry', 'borry', 'borry', 'Саня', 'Ваня', 'Маня', 'sovvy', 'covvy', 'borry', 'Саня', 'Ваня', 'Маня', 'Пётр', 'Другой Пётр', 'с', 'т', 'р', 'о', 'к', 'а']<jupyter_text>Может возникнуть ситуация, что нам требуется проверить, есть ли элемент в листе, это проверяется с помощью конструкции **if else**<jupyter_code>if 'borry' in group:
    print('it`s here')<jupyter_output>it`s here<jupyter_text>Проверить, что элемент отсутствует в списке можно аналогично:<jupyter_code>if 'berry' not in group:
    print('null')<jupyter_output>null<jupyter_text>Может потребоваться не просто проверить элемент, а еще получить его индекс, это провернуть можно с помощью метода **.index(element)**<jupyter_code>print(group.index('sovvy'))<jupyter_output>0<jupyter_text>Важно! И проверка и вывод индекса, как ты уже заметил, происходит только по первому вхождению. Если требуется найти все совпадающие элементы, можно воспользоваться циклом **for**<jupyter_code>j = 0
for i in group: 
    if i == 'sovvy':
        print('['+ str(j) +']' + i)
    j += 1<jupyter_output>[0]sovvy
[7]sovvy<jupyter_text>Найти количество элементов:<jupyter_code>print(group.count('sovvy'))<jupyter_output>2<jupyter_text>Удалить элемент из списка (удалит первое вхождение):<jupyter_code>print('начальный список --', group)
group.remove('sovvy')
print('обновлённый список --', group)<jupyter_output>начальный список -- ['sovvy', 'worry', 'borry', 'borry', 'Саня', 'Ваня', 'Маня', 'sovvy', 'covvy', 'borry', 'Саня', 'Ваня', 'Маня', 'Пётр', 'Другой Пётр', 'с', 'т', 'р', 'о', 'к', 'а']
обновлённый список -- ['worry', 'borry', 'borry', 'Саня', 'Ваня', 'Маня', 'sovvy', 'covvy', 'borry', 'Саня', 'Ваня', 'Маня', 'Пётр', 'Другой Пётр', 'с', 'т', 'р', 'о', 'к', 'а']<jupyter_text>Удалять элементы можно и по индексу при помощи конструкции **del listname[*index*]**. К примеру удалим всех Вань из списка:<jupyter_code>j = 0
for i in group: 
    if i == 'Ваня':
        del group[j]
    j += 1
print(group)<jupyter_output>['worry', 'borry', 'borry', 'Саня', 'Маня', 'sovvy', 'covvy', 'borry', 'Саня', 'Маня', 'Пётр', 'Другой Пётр', 'с', 'т', 'р', 'о', 'к', 'а']<jupyter_text>Лист можно сортировать. Есть 2 способа: без изменения исходного списка, с изменением исхоного списка:<jupyter_code># без изменения исхожного списка

sorted_group = sorted(group)
print(sorted_group)

# с изменением исходного
group.sort()
print(group)<jupyter_output>['borry', 'borry', 'borry', 'covvy', 'sovvy', 'worry', 'Другой Пётр', 'Маня', 'Маня', 'Пётр', 'Саня', 'Саня', 'а', 'к', 'о', 'р', 'с', 'т']
['borry', 'borry', 'borry', 'covvy', 'sovvy', 'worry', 'Другой Пётр', 'Маня', 'Маня', 'Пётр', 'Саня', 'Саня', 'а', 'к', 'о', 'р', 'с', 'т']<jupyter_text>Отразить список можно не только через [::-1] (это, к слову, не изменить первоначальный список, а просто отобразит его перевернутым), но еще и при помощи методов **reversed()** и **.reverse()**<jupyter_code>reversed(group) # не изменяет исходный список

group.reverse()
print(group) # изменяет исходный список<jupyter_output>['т', 'с', 'р', 'о', 'к', 'а', 'Саня', 'Саня', 'Пётр', 'Маня', 'Маня', 'Другой Пётр', 'worry', 'sovvy', 'covvy', 'borry', 'borry', 'borry']<jupyter_text>Двумерные спискиДвумерные списки задаются точно так же, как и обычные, но у них есть расширенная возможность индексации.<jupyter_code>table = [[0, 5, 12], [3, 6, 9], [8, 34, 69]] # и тд. т.е. в списке хранятся еще списки

# давай посмотрим длину списка, и получим элемент с индексом 0
print('Длина списка --', len(table), 'элемент под индексом 0:', table[0])
# т.е. в нашем списке всего 3 элемента, и каждый из этих элементов -- список, 
# так как при запросе жлемента с индексом 0 нам вернулся список

# давай попробуем прменить расширенную индексацию (такая же индексация применяется при индексировании таблиц [row][cell])
print(table[0][1]) # обратились к элементу 0 и получили из того элемента элемент с индексом 1<jupyter_output>5<jupyter_text>Множества и словари МножестваМножества -- родственники листов (списков), но есть существенные отличия:<jupyter_code>many = set() # создание пустого множества

manymany = {'bill', 'fill', 'fill', 'alex', 'dankeyYy'} # инициализирование множества при создании
print(manymany) # в множество будут добавлены только уникальные значения
print('bill' in manymany) # поиск совпадений в множестве<jupyter_output>True<jupyter_text>Методы для работы со множествами:<jupyter_code>manymany.add('bob') # добавление элемента
print(manymany)

manymany.discard('dankey') # удаление элемента (в случае отсутствия элемента не генерирует ошибку)
print(manymany)

manymany.remove('dankeyYy') # удаление элемента (в случае отсутствия элемента генерирует ошибку)
print(manymany)

manymany.clear() # очистка множества
print(manymany)<jupyter_output>{'fill', 'alex', 'bob', 'bill', 'dankeyYy'}
{'fill', 'alex', 'bob', 'bill', 'dankeyYy'}
{'fill', 'alex', 'bob', 'bill'}
set()<jupyter_text>СловариСловари похожи на множества, но хранят жанныи в виде ключ=значение:<jupyter_code>dict, {} # создать пустой словарь

dict1 = {'a': 'Саня', 'b': 'Костя'}
print(dict1)
print(dict1['a'])<jupyter_output>{'a': 'Саня', 'b': 'Костя'}
Саня<jupyter_text>В словари так же можно добавлять значение, удалять значения, искать значения:<jupyter_code>dict1['c'] = 'Некита' # добавление пары
print(dict1)
print(dict1['c'])

dict1['a'] = '<NAME>' # Изменить существующее значение
print(dict1)
print(dict1['a'])

print('a' in dict1) # поиск ключа в словаре
print('d' not in dict1) # проверка на остуствие ключа

print(dict1.get('a')) # безопасное получение значения ключа (в случае отсутствия вернет None, не сгенерирует ошибку)
print(dict1['a']) # небезопасное получение значения ключа (в случае отсутствия сгенерирует ошибку)

del dict1['a'] # удаление пары 
print(dict1)<jupyter_output>{'a': '<NAME>', 'b': 'Костя', 'c': 'Некита'}
Некита
{'a': '<NAME>', 'b': 'Костя', 'c': 'Некита'}
Н<NAME>аня
True
True
Не Саня
Не Саня
{'b': 'Костя', 'c': 'Некита'}<jupyter_text>Перебор словарей:<jupyter_code>for key in dict1: # перебрать ключи
    print(key, end=' ')

print('\n')
    
for key in dict1.keys(): # перебор ключей (явный)
    print(key, end= ' ')
    
print('\n')
    
for value in dict1.values(): # перебор значений
    print(value, end=' ')
    
print('\n')

for key, value in dict1.items(): # перебор пар ключ-значение
    print(key, value, end='; ')<jupyter_output>b c 

b c 

Костя Некита 

b Костя; c Некита;<jupyter_text>Ключи должны быть уникальными, но значения могут повторяться. Более того, к одному ключу можно привязать несколько значений (список)<jupyter_code>d = { 'люди': ['Саня', 'Костя', 'Никита'], 'машины': ['BMV', 'Lada', 'untitled']}
print(d.get('люди'))<jupyter_output>['Саня', 'Костя', 'Никита']<jupyter_text>Функции (методы) Что бы было удобнее использовать код были придуманы функции.Функция имеет такую конструкцию **def func_name(paramete, parameter, ...):**Параметр не обязателен, все зависит от контекста. К примеру напишем функцию, которая сравнит 2 числа и назовет большее:<jupyter_code>def maximum(a, b):
    if a > b:
        print(a)
    else:
        print(b)<jupyter_output><empty_output><jupyter_text>Сейчас эта функция ничего не возвращает и никак не используется, потому что мы её не вызывали. Давай вызовем, передав аргументы a и b:<jupyter_code>maximum(14, 23)<jupyter_output>23<jupyter_text>Мы вызвали функцию **maximum** и передали в нее значение аргумента a и значение аргумента b.Конкретно эта функция не возвращает результат, а просто выполняется. Вернуть результат вычислений можно при помощи ключевого слова **return**:<jupyter_code>import math

def sqr_calc(a):
    result = math.sqrt(a)
    return result
print(sqr_calc(9))<jupyter_output>3.0<jupyter_text>Что сейчас произошло: мы вызвали функцию **sqr_calc**, передав в качестве аргумента значение a, которое равно 9, в функции, при помощи импортированной библиотеки **math** рассчитался квадратный корень числа и функция вернула нам результат расчёта, который мы вывели на экран.Так же возвращаемое значение можно не просто вывести на экран, а записать его в какую-нибудь переменную:<jupyter_code>result = sqr_calc(9)
print(result)<jupyter_output>3.0<jupyter_text>Важно! Когда код достигает **return** -- дальнейший код в этой функции не выполнится, так как **return** вернет значение в вызывающий метод и прервет дальнейшее выполнение своей функции. Всё, что будет написанно после **return** на этом же уровне кода называется *недостижимый код*.Но так как у нас может быть использованы if else конструкции, которые имеют разный уровень табуляции или же циклы, то вполне уместно использовать несколько **return**<jupyter_code>def calc(a):
    if a > 5:
        result = a * 10
        return result
    else:
        return 0
print(calc(7))<jupyter_output>70<jupyter_text>Как уже говорилось ранее, функция может иметь некоторые определенные параметры или не иметь параметров вовсе, но в питоне есть прикольная штука -- функция может иметь нопределенное количество параметров, указываются они через \*:<jupyter_code>def multi(*a):
    
    temp = []
    result = 0
    
    # умножим каждый аргумент на 2 и положим каждый результат в список temp
    for i in range(len(a)):
        temp.append(a[i] * 2)
        
    # найдем среднее значений списка temp
    for i in range(len(temp)):
        result += temp[i]
        result /= len(temp)
        
    # вернем результат
    return result
result = multi(2, 4, 8)
print(result)<jupyter_output>6.37037037037037<jupyter_text>Мы также можем передавать не только строго только обязательные параметры, мы так же можем передавать или не передавать необяхательный параметр, который, в случае, если параметр не будет передаваться, будет испрользовать значение по умолчанию:<jupyter_code>def multi2(list_a, b=2):
    
    temp = []
    result = 0
    
    # умножим каждый аргумент на 2 и положим каждый результат в список temp
    for i in range(len(list_a)):
        temp.append(list_a[i] * b)
        
    # найдем среднее значений списка temp
    for i in range(len(temp)):
        result += temp[i]
        result /= len(temp)
        
    # вернем результат
    return result
c = multi2([2, 4, 8], 5) # в качестве аргумента b передаём значение 5, это будет наш множитель
print(c)
c = multi2([2, 4, 8]) # не передаем никакого значения аргумента b, b будет = 2 по дефолту
print(c)<jupyter_output>6.37037037037037
{'fraction_non_alphanumeric': 0.137180910099889, 'fraction_numerical': 0.0166798794989694, 'mean_word_length': 5.0506523407521104, 'pattern_counts': {'":': 0, '<': 209, '<?xml version=': 0, '>': 216, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 4, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '61', 'dir': 'jupyter-structured-clean-dedup', 'id': '540105', 'license': 'MIT', 'n_tokens_mistral': 13881, 'n_tokens_neox': 15208, 'n_words': 3691, 'path': 'Python-base.ipynb', 'repo_name': 'mr-luntik/python-base-syntax', 'size': '31535'}