Есть ли лучший способ конвертировать список в словарь в Python с ключами, но нет значений?

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

Единственный способ, с помощью которого я мог это сделать, – возразить.

«Использование списков в том случае, когда результат игнорируется, является вводящим в заблуждение и неэффективным.

 myList = ['a','b','c','d'] myDict = {} x=[myDict.update({item:None}) for item in myList] >>> myDict {'a': None, 'c': None, 'b': None, 'd': None} 

Это работает, но есть ли лучший способ сделать это?

    Используйте dict.fromkeys :

     >>> my_list = [1, 2, 3] >>> dict.fromkeys(my_list) {1: None, 2: None, 3: None} 

    Значения по умолчанию None , но вы можете указать их как необязательный аргумент:

     >>> my_list = [1, 2, 3] >>> dict.fromkeys(my_list, 0) {1: 0, 2: 0, 3: 0} 

    Из документов:

    a.fromkeys (seq [, value]) Создает новый словарь с ключами из seq и значениями, установленными в значение.

    dict.fromkeys – метод класса, который возвращает новый словарь. Значение по умолчанию – None. Новое в версии 2.3.

    Вы можете использовать набор вместо dict:

     >>> myList=['a','b','c','d'] >>> set(myList) set(['a', 'c', 'b', 'd']) 

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

    Чтобы ответить на вопрос о производительности оригинального опроса (для поиска в dict vs set ), несколько удивительно, что поиск в dict может быть очень быстрым (в Python 2.5.1 на моем довольно медленном ноутбуке), предполагая, например, что половина запросов не удалась и половина успеха. Вот как можно разобраться:

     $ python -mtimeit -s'k=dict.fromkeys(range(99))' '5 in k and 112 in k' 1000000 loops, best of 3: 0.236 usec per loop $ python -mtimeit -s'k=set(range(99))' '5 in k and 112 in k' 1000000 loops, best of 3: 0.265 usec per loop 

    делая каждую проверку несколько раз, чтобы убедиться, что они повторяемы. Таким образом, если эти 30 наносекунд или менее на медленном ноутбуке находятся в крайне важном узком месте, возможно, стоит пойти на непонятное решение dict.fromkeys а не на простой, очевидный, читаемый и четко правильный set (необычный – почти неизменно в Python простое и прямое решение имеет преимущества производительности тоже).

    Конечно, нужно проверить с помощью собственной версии Python, машины, данных и соотношения успешных тестов с ошибкой и подтвердить с помощью чрезвычайно точного профилирования, что бритье на 30 наносекунд (или что-то еще) от этого поиска будет иметь важное значение.

    К счастью, в подавляющем большинстве случаев это окажется совершенно ненужным … но так как программисты все равно будут одержимы бессмысленными timeit , независимо от того, сколько раз им говорят об их нерелевантности, модуль timeit находится прямо там, в стандартную библиотеку, чтобы сделать эти в основном бессмысленные микро-тесты легкими, как пирог в любом случае! -)

    И вот довольно неправильный и неэффективный способ сделать это с помощью карты:

     >>> d = dict() >>> map (lambda x: d.__setitem__(x, None), [1,2,3]) [None, None, None] >>> d {1: None, 2: None, 3: None} 

    Вы можете использовать понимание списка:

     my_list = ['a','b','c','d'] my_dict = dict([(ele, None) for ele in my_list]) 

    Возможно, вы можете использовать itertools:

     >>>import itertools >>>my_list = ['a','b','c','d'] >>>d = {} >>>for x in itertools.imap(d.setdefault, my_list): pass >>>print d {'a': None, 'c': None, 'b': None, 'd': None} 

    Для огромных списков, может быть, это очень хорошо: P