Допустим есть у нас задача. Есть список чисел:

1 2 3 4 5 6 7 8 9 10

мы запрашиваем у пользователя число. И надо вывести информацию о том сколько чисел и какие остатки от деления они имеют.

Например, пользователь вводит 3, и я вывожу:

казалось бы, как я могу это сделать? Например взять завести три переменные и заполнять их в цикле:

arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

mod_0 = 0
mod_1 = 0
mod_2 = 0

for x in arr:
    if x % 3 == 0:
        mod_0 += 1
    if x % 3 == 1:
        mod_1 += 1
    if x % 3 == 2:
        mod_2 += 1

но проблема в том, что пользователь может ведь ввести в принципе какое угодно число. Например, 100 и тогда получается, что мне надо завести 100 переменных, так как остатков от деления на 100 – 100 штук (от 0 до 99)

И как в такой ситуации быть?

Специально для таких случаев существует специальная структура данных которая называется словарик. Оно представляет из себя специальный объект который хранит соответствия типа ключ -> значение.

Ну, например, проводили мы какие-то наблюдения за погодой. И получилась у нас следующая таблица наблюдений за средней температурой в течении первых шести месяцев года:

Месяц Средняя температура
Январь -20 градусов
Февраль -10 градусов
Март 0 градусов
Апрель 5 градусов
Май 20 градусов
Июнь 25 градусов

На питоне мы можем записать такую информацию следующим образом:

temperature = {
    "Январь": -20,
    "Февраль": -10,
    "Март": 0,
    "Апрель": 5,
    "Май": 20,
    "Июнь": 25,
}

то есть объявили переменную и особым способом запихали в нее информацию. То, что находится слева от двоеточия – это называется ключ (в нашем случае в качестве ключа у нас название месяца), а то что находится справа от двоеточия называется значением.

И теперь если нам вдруг захочется узнать о средней температуре в апреле, мы можем просто написать так

print(temperature["Апрель"]) # выдаст 5

то есть этот словарик немного напоминает массив только когда мы хотим получить значение какого-то элемента мы передаем не его индекс, а его ключ (например, Апрель)

Помимо того, что мы можем получать значения. Мы можем изменять их, например, поменяем температуру в Апреле:

temperature = {
    "Январь": -20,
    "Февраль": -10,
    "Март": 0,
    "Апрель": 5,
    "Май": 20,
    "Июнь": 25,
}
print(temperature)

temperature["Апрель"] = 10  # обновил значение
print(temperature)

тестим

более того мы можем даже добавлять новые ключи, просто присваивая им значения:

temperature = {
    "Январь": -20,
    "Февраль": -10,
    "Март": 0,
    "Апрель": 5,
    "Май": 20,
    "Июнь": 25,
}
print(temperature)

temperature["Июль"] = 30  # добавил новый ключ
print(temperature)

мы можем проверить наличие какого-то ключа в словарике через оператор in

temperature = {
    "Январь": -20,
    "Февраль": -10,
    "Март": 0,
    "Апрель": 5,
    "Май": 20,
    "Июнь": 25,
}

if "Июнь" in temperature:
    print(f"Температура в июне: {temperature['Июнь']}")
    
if "Сентябрь" not in temperature:
    print(f"У нас нет данных по сентябрю")

вообще очень важно проверять наличие ключа в словарике, потому что если его там не будет, и вы попробуете вывести значение по не существующему ключу, то питон выплюнет ошибку:

temperature = {
    "Январь": -20,
    "Февраль": -10,
    "Март": 0,
    "Апрель": 5,
    "Май": 20,
    "Июнь": 25,
}
print(temperature['Сентябрь'])

в этом случае вам надо сначала загнать какое-нибудь значение по умолчанию

temperature = {
    "Январь": -20,
    "Февраль": -10,
    "Март": 0,
    "Апрель": 5,
    "Май": 20,
    "Июнь": 25,
}

if 'Сентябрь' not in temperature:
    temperature['Сентябрь'] = 0

print(temperature['Сентябрь'])

но так как писать сразу if и присвоение значения по умолчанию лениво, то есть специальная функция которая делает эти два действия в одну строчку

temperature = {
    "Январь": -20,
    "Февраль": -10,
    "Март": 0,
    "Апрель": 5,
    "Май": 20,
    "Июнь": 25,
}

# вместо этого
# if 'Сентябрь' not in temperature:
#     temperature['Сентябрь'] = 0

# пишем так
temperature.setdefault("Сентябрь", 0)
print(temperature['Сентябрь'])  # выдаст 0

# можем поменять значение
temperature['Сентябрь'] = 10
temperature.setdefault("Сентябрь", 0)  # и теперь эта строчка никак не повлияет на значение на ключа
print(temperature['Сентябрь']) # то есть тут все равно будет выдано 10

теперь вернемся к нашей исходной задаче:

Надо вывести информацию о том сколько чисел и какие остатки от деления они имеют. Например, пользователь вводит 3, и я вывожу:

так как словарики позволяют мне динамически создавать ключи. То я могу завести пустой словарик и заполнять его при обходе массива, и в качестве ключа использовать остаток от деления, а в качестве значения количество элементов с таким остатком от деления:

arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

result = {}  # завожу пустой словарик

for x in arr:
    # устанавливаю значения ключа по умолчанию на 0,
    # эта функция сработает только раз для каждого остатка от деления
    result.setdefault(x % 3, 0)

    result[x % 3] += 1  # увеличиваю значение ключа

# выводим результат
for key in result:
    print(f"{result[key]} числа имеют остаток от деления числа на 3 равным {key}")

запускаем:

теперь можно еще число у юзера запрашивать

r = input("Введите значение: ")
r = int(r)

arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

result = {}  # завожу пустой словарик

for x in arr:
    result.setdefault(x % r, 0)
    result[x % r] += 1

for key in result:
    print(f"{result[key]} числа имеют остаток от деления числа на {r} равным {key}")

Задание

Решить предыдущую задачу используя словарик