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 шт):
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)) # передаем часть списка ключей
можно еще так:
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
Вот вариант с 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))