Fromkeys: примеры (PYTHON)
fromkeys(iterable[, value]): dictОписание функции fromkeys
Метод fromkeys() является классовым методом словаря (dict) в Python. Его используют для создания нового словаря из заданной последовательности ключей, где всем ключам присваивается одинаковое значение.
Функция применяется, когда требуется быстро инициализировать словарь с набором ключей и единым стартовым значением. Это удобно для установки значений по умолчанию, счетчиков или флагов.
Синтаксис и аргументы
Синтаксис: dict.fromkeys(seq[, value])
Параметры:
seq: Обязательный параметр. Последовательность (итерируемый объект), элементы которой становятся ключами нового словаря. Может быть списком, кортежем, строкой, множеством или range.value: Необязательный параметр. Значение, которое присваивается каждому ключу. По умолчанию равноNone.
Возвращаемое значение:
Функция возвращает новый объект словаря (dict). Исходный словарь, у которого вызван метод, не изменяется.
Простые примеры использования
Создание словаря со значением по умолчанию None:
keys = ['name', 'age', 'city']
result = dict.fromkeys(keys)
print(result){'name': None, 'age': None, 'city': None}Создание словаря с заданным значением:
keys = ('a', 'b', 'c')
result = dict.fromkeys(keys, 0)
print(result){'a': 0, 'b': 0, 'c': 0}Использование строки как последовательности ключей:
result = dict.fromkeys("hello", True)
print(result){'h': True, 'e': True, 'l': True, 'o': True}Обратите внимание, что ключ 'l' встречается в строке дважды, но в словаре он будет единственным, так как ключи словаря уникальны.
Похожие функции в Python
Словарное включение (dict comprehension): Позволяет более гибко создавать словари, используя выражения для формирования и ключей, и значений. Предпочтительнее, когда нужно вычислить значение для каждого ключа индивидуально.
keys = ['x', 'y', 'z']
d = {k: k.upper() for k in keys}
print(d){'x': 'X', 'y': 'Y', 'z': 'Z'}Конструктор dict() с итерируемым объектом: Может принимать список кортежей (пар ключ-значение). Используется, когда пары ключ-значение известны заранее и они разные.
pairs = [("one", 1), ("two", 2)]
d = dict(pairs)
print(d){'one': 1, 'two': 2}Метод fromkeys() эффективнее, когда нужно присвоить всем ключам одно и то же простое значение.
Типичные ошибки
Изменяемое значение по умолчанию: Если вторым аргументом передается изменяемый объект (например, список), то все ключи будут ссылаться на один и тот же объект. Изменение этого объекта по одному ключу затронет все остальные.
keys = ['a', 'b', 'c']
d = dict.fromkeys(keys, [])
d['a'].append(1)
print(d){'a': [1], 'b': [1], 'c': [1]}Вместо этого, для независимых изменяемых значений лучше использовать словарное включение.
keys = ['a', 'b', 'c']
d = {key: [] for key in keys}
d['a'].append(1)
print(d){'a': [1], 'b': [], 'c': []}Использование неитерируемого объекта в качестве последовательности ключей:
result = dict.fromkeys(123) # Ошибка: int не является итерируемым
print(result)TypeError: 'int' object is not iterable
Потеря данных из-за дублирования ключей: Если в последовательности есть повторяющиеся элементы, в словаре останется только один ключ с последним присвоенным значением (хотя в fromkeys значение одинаковое, но важно понимать это поведение).
keys = [1, 2, 2, 3]
result = dict.fromkeys(keys, 'x')
print(result){1: 'x', 2: 'x', 3: 'x'}Изменения в последних версиях Python
Специфических изменений в поведении метода dict.fromkeys() в последних основных версиях Python (3.x) не было. Это стабильный и давно существующий метод.
Однако, начиная с Python 3.7, официально гарантируется, что порядок ключей в словаре соответствует порядку их вставки. Это касается и словарей, созданных через fromkeys(): порядок ключей будет соответствовать порядку их следования в переданной последовательности.
# В Python 3.7+
result = dict.fromkeys(['z', 'a', 'c'], 0)
print(list(result.keys()))['z', 'a', 'c']
Расширенные примеры
Использование range для генерации ключей:
result = dict.fromkeys(range(5), "initial")
print(result){0: 'initial', 1: 'initial', 2: 'initial', 3: 'initial', 4: 'initial'}Создание словаря с вычисляемым значением по умолчанию через функцию. Сам метод fromkeys не поддерживает функцию в качестве значения, но можно использовать словарное включение. Однако, если функция уже возвращает нужное значение, его можно передать:
def get_default():
return "default"
keys = ['k1', 'k2']
# Передаем результат вызова функции, а не саму функцию
result = dict.fromkeys(keys, get_default())
print(result){'k1': 'default', 'k2': 'default'}Если нужно, чтобы каждое значение было результатом отдельного вызова функции, нужен другой подход.
Использование множества (set) в качестве последовательности ключей. Порядок ключей в результате может быть произвольным, так как множество не гарантирует порядок.
keys_set = {'apple', 'banana', 'cherry'}
result = dict.fromkeys(keys_set, 1)
print(result){'banana': 1, 'apple': 1, 'cherry': 1}Создание вложенной структуры данных с использованием изменяемого значения (с осторожностью):
keys = ['config1', 'config2']
# Плохой пример: все ключи ссылаются на один и тот же словарь
default_dict = dict.fromkeys(keys, {'enabled': False})
default_dict['config1']['enabled'] = True
print(default_dict){'config1': {'enabled': True}, 'config2': {'enabled': True}}Правильный вариант:
keys = ['config1', 'config2']
result = {key: {'enabled': False} for key in keys}
result['config1']['enabled'] = True
print(result){'config1': {'enabled': True}, 'config2': {'enabled': False}}Использование fromkeys для быстрого создания «маски» или набора флагов из списка возможных значений:
all_options = ['auto_save', 'dark_mode', 'notifications']
user_settings = dict.fromkeys(all_options, False)
user_settings['dark_mode'] = True # Пользователь включил только темную тему
print(user_settings){'auto_save': False, 'dark_mode': True, 'notifications': False}Аналоги функции в других языках
JavaScript: Аналогом является Object.fromEntries() в комбинации с map(), либо цикл. Прямого аналога нет.
// Использование map и Object.fromEntries
let keys = ['a', 'b', 'c'];
let value = 10;
let obj = Object.fromEntries(keys.map(k => [k, value]));
console.log(obj);{ a: 10, b: 10, c: 10 }PHP: Функция array_fill_keys() выполняет ту же роль.
$keys = ['cat', 'dog', 'fish'];
$value = 'pet';
$result = array_fill_keys($keys, $value);
print_r($result);Array
(
[cat] => pet
[dog] => pet
[fish] => pet
)Java: Прямого аналога нет, обычно используется цикл для инициализации Map.
// Java пример с HashMap
import java.util.*;
List keys = Arrays.asList("k1", "k2", "k3");
Map map = new HashMap<>();
for (String key : keys) {
map.put(key, 100);
}
System.out.println(map); {k1=100, k2=100, k3=100}C#: Используется LINQ метод ToDictionary.
var keys = new List { "id", "name" };
var dict = keys.ToDictionary(key => key, key => "");
Console.WriteLine(string.Join(", ", dict)); [id, ], [name, ]
Golang: Аналога нет, используется цикл.
keys := []string{"Jan", "Feb", "Mar"}
value := 0
dict := make(map[string]int)
for _, key := range keys {
dict[key] = value
}
fmt.Println(dict)map[Feb:0 Jan:0 Mar:0]