Python. Напишите функцию которая создаёт словарь из двух списков разной длины

Есть два списка разной длины. В первом содержатся ключи, а во втором — значения. Напишите функцию make_dict, которая создаёт из этих ключей и значений словарь. Если ключу не хватило значения, в словаре должно быть значение None. Функция должна игнорировать значения, которым не хватило ключей и должна возвращать словарь без значения None.

Я попытался написать код:

k = ["key_1", "key_2", "key_3", "key_4", "key_5"]
v = ["val_1", "val_2", "val_3"]

make_dict = {}
x = 0

while x < len(k):
    try:
        make_dict[k[x]] = v[x]
        x = x + 1
    except:
        make_dict[k[x]] = "None"
    x = x + 1

print(make_dict)

Она возвращает созданный словарь.

Но у меня не получается из этого создать функцию. А также не пойму как сделать "Значения, которым не хватило ключей, нужно игнорировать."

Пока что, ответ от пользователя Алексей Р является наиболее актуальным. Вариант от Kirill Kondratenko у меня выдаёт ошибку. Но всё же хотелось бы увидеть решения которые будут полностью отвечать условиям задачи. А именно - Сама функция (def) должна игнорировать значения, которым не хватило ключей и должна возвращать словарь без значения None.


Ответы (4 шт):

Автор решения: Kirill Kondratenko
def make_dict(test_keys, test_values):
    for i in range(0, len(test_keys) - len(test_values)):
        test_values.append(None)
    res = {}
    for key in test_keys:
        for value in test_values:
            res[key] = value
            test_values.remove(value)
            break
    return res

Пример 1:

test_keys = ["alfa", "beta", "gamma"]
test_values = [1, 4, 5, 6, 7, 8]
make_dict(test_keys, test_values)

{'alfa': 1, 'beta': 4, 'gamma': 5}

Пример 2:

test_keys = ["alfa", "beta", "gamma"]
test_values = [1, 4]
make_dict(test_keys, test_values)

{'alfa': 1, 'beta': 4, 'gamma': None}
→ Ссылка
Автор решения: Алексей Р

Решение с zip_longest

from itertools import zip_longest

k = ["key_1", "key_2", "key_3", "key_4", "key_5"]
v = ["val_1", "val_2", "val_3"]


def make_dict(keys: list, values: list) -> dict:
    return {k: v for k, v in zip_longest(keys, values) if k}


print(make_dict(k, v))
print(make_dict(k[:2], v))  # передаем часть списка ключей
{'key_1': 'val_1', 'key_2': 'val_2', 'key_3': 'val_3', 'key_4': None, 'key_5': None}
{'key_1': 'val_1', 'key_2': 'val_2'}

Решение с zip

k = ["key_1", "key_2", "key_3", "key_4", "key_5"]
v = ["val_1", "val_2", "val_3"]


def make_dict(keys: list, values: list) -> dict:
    return {k: v for k, v in (zip(keys, values + [None] * (len(keys) - len(values))))}  # или dict(zip(keys, values + [None] * (len(keys) - len(values))))


print(make_dict(k, v))
print(make_dict(k[:2], v))  # передаем часть списка ключей

Решение без zip

k = ["key_1", "key_2", "key_3", "key_4", "key_5"]
v = ["val_1", "val_2", "val_3"]


def make_dict(keys: list, values: list) -> dict:
    return {k: values[i] if i < len(values) else None for i, k in enumerate(keys)}


print(make_dict(k, v))
print(make_dict(k[:2], v))  # передаем часть списка ключей

Решение с применением срезов
Если список значений уже исчерпан, а ключи еще есть, то выражение values[i:i + 1] or None возвращает None как значение.

k = ["key_1", "key_2", "key_3", "key_4", "key_5"]
v = ["val_1", "val_2", "val_3"]


def make_dict(keys: list, values: list) -> dict:
    return {k: values[i:i + 1] or None for i, k in enumerate(keys)}


print(make_dict(k, v))
print(make_dict(k[:2], v))  # передаем часть списка ключей
→ Ссылка
Автор решения: strawdog

можно еще так:

def make_dict(k, v):
    d = dict.fromkeys(k)
    ik = iter(k)
    iv = iter(v)
    for i in range(min(len(k), len(v))):
        d[next(ik)] = next(iv)
    return d
→ Ссылка
Автор решения: minaton

Вот вариант с zip и со срезами. Не однострочник, но зато есть проверка на хешируемость ключа и убираются дубли из списка ключей.

from typing import Optional

def make_dict(keys_list: list, values_list: list) -> Optional[dict]:
    try:
        keys_set_list = list(dict.fromkeys(keys_list))
        result = dict(zip(keys_set_list, values_list))
        {result.setdefault(x) for x in keys_set_list[len(values_list):]}
        return result
    except TypeError as e:
        print(e)

Можно попробовать вот на таких данных:

k = ["key_1", "key_2", "key_3", "key_4", "key_5", "key_3", "key_1"]
v = ["val_1", "val_2", "val_3"]
print(make_dict(k, v))


k = ["key_1", [1, 2], "key_3"]
v = ["val_1", "val_2", "val_3"]
print(make_dict(k, v))
→ Ссылка