Вопрос по python, list-comprehension, dictionary – Понимание словаря Python

336

Можно ли создать словарь понимания на Python (для ключей)?

Без понимания списка вы можете использовать что-то вроде этого:

l = []
for n in range(1, 11):
    l.append(n)

Мы можем сократить это до понимания списка.l = [n for n in range(1, 11)]

Тем не менее, скажем, я хочу установить словарьs ключи к тому же значению. Я могу сделать: я

d = {}
for n in range(1, 11):
     d[n] = True # same value for each

мы пробовали это:

d = {}
d[i for i in range(1, 11)] = True

Тем не менее, я получаюSyntaxError на .for

Кроме того (я немне не нужна эта часть, но просто интересно), вы можете установить словарь?s ключи к множеству разных значений, например:

d = {}
for n in range(1, 11):
    d[n] = n

Возможно ли это при понимании словаря?

d = {}
d[i for i in range(1, 11)] = [x for x in range(1, 11)]

Это также поднимаетSyntaxError на .for

Для будущих читателей info: массивы NumPy позволяют вам устанавливать несколько элементов на одно значение или список значений, как выпытаюсь сделать. Хотя, если вы неу меня уже есть причина использовать NumPy, этоСкорее всего, это не стоит только для этой функции. David Z

Ваш Ответ

8   ответов
10

Рассмотрим этот пример подсчета появления слов в списке с использованием словарного понимания.

my_list = ['hello', 'hi', 'hello', 'today', 'morning', 'again', 'hello']
my_dict = {k:my_list.count(k) for k in my_list}
print(my_dict)

И результат

{'again': 1, 'hi': 1, 'hello': 3, 'today': 1, 'morning': 1}
Это интересно, но не самое эффективное, как выбуду считать ключи какПривет' многократно FuriousGeorge
11

Используйте dict () в списке кортежей, это решение позволит вам иметь произвольные значения в каждом списке, если они имеют одинаковую длину

i_s = range(1, 11)
x_s = range(1, 11)
# x_s = range(11, 1, -1) # Also works
d = dict([(i_s[index], x_s[index], ) for index in range(len(i_s))])
Как примечание стороны, это то же самое, чтоd = dict(zip(i_s,x_s)) mgilson
-3

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

d[tuple([i for i in range(1,11)])] = True
Это неделать то, что хотел ОП ... Ned Batchelder
25
>>> {i:i for i in range(1, 11)}
{1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10}
7

Основная цель понимания списка состоит в создании нового списка на основе другого без изменения или уничтожения исходного списка.

Вместо того чтобы писать

    l = []
    for n in range(1, 11):
        l.append(n)

или же

    l = [n for n in range(1, 11)]

ты должен писать только

    l = range(1, 11)

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

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

    old_dict = {'a': 1, 'c': 3, 'b': 2}
    new_dict = { key:'your value here' for key in old_dict.keys()}

Вы'получаю SyntaxError, потому что, когда вы пишете

    d = {}
    d[i for i in range(1, 11)] = True

вы'в основном говорю: "Установить мой ключя для я в диапазоне (1, 11) ' к истине а также "я для меня в диапазоне (1, 11) " это не правильный ключ, это 'просто синтаксическая ошибка. Если dicts поддерживает списки в качестве ключей, вы должны сделать что-то вроде

    d[[i for i in range(1, 11)]] = True

и не

    d[i for i in range(1, 11)] = True

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

143

Вы можете использоватьdict.fromkeys метод класса ...

>>> dict.fromkeys(range(5), True)
{0: True, 1: True, 2: True, 3: True, 4: True}

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

Ноделатьне используйте это с изменяемыми объектами:

d = dict.fromkeys(range(5), [])
# {0: [], 1: [], 2: [], 3: [], 4: []}
d[1].append(2)
# {0: [2], 1: [2], 2: [2], 3: [2], 4: [2]} !!!

Если вы нет на самом деленеобходимость чтобы инициализировать все ключи,defaultdict также может быть полезным:

from collections import defaultdict
d = defaultdict(True)

Чтобы ответить на вторую часть, вам нужно именно это понимание:

{k: k for k in range(10)}

Вы, вероятно, не должнысделать это, но вы также можете создать подклассdict который работает чем-то вродеdefaultdict если вы переопределите:__missing__

>>> class KeyDict(dict):
...    def __missing__(self, key):
...       #self[key] = key  # Maybe add this also?
...       return key
... 
>>> d = KeyDict()
>>> d[1]
1
>>> d[2]
2
>>> d[3]
3
>>> print(d)
{}
Обратите внимание, что в случаеd = defaultdict(lambda: True)лямбда не обязательна, поскольку Истина есть (или не должнаt) быть изменчивым rhbvkleef
19

Мне очень нравится комментарий @mgilson, так как, если у вас есть две итерации, одна из которых соответствует ключам, а другая значения, вы также можете сделать следующее.

keys = ['a', 'b', 'c']
values = [1, 2, 3]
d = dict(zip(keys, values))

дающий

d = {'a': 1, 'b': 2, 'c': 3}

454

Естьсловарь в Python 2.7+но они неработать не так, как тыпытаюсь Как и понимание списка, они создаютновый толковый словарь; вы можете'Используйте их для добавления ключей в существующий словарь. Кроме того, вы должны указать ключи и значения, хотя, конечно, вы можете указать фиктивное значение, если хотите.

>>> d = {n: n**2 for n in range(5)}
>>> print d
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

Если вы хотите установить их все в True:

>>> d = {n: True for n in range(5)}
>>> print d
{0: True, 1: True, 2: True, 3: True, 4: True}

То, что вы, похоже, просите, это способ установить несколько ключей одновременно в существующем словаре. Там'Нет прямого пути для этого. Вы можете зациклить, как вы уже показали, или вы можете использовать словарь, чтобы создать новый dict с новыми значениями, а затем сделатьoldDict.update(newDict) слить новые ценности в старый диктат.

Обратите внимание, что если вы хотите создать словарь со всеми одинаковыми значениями, используйтеdict.fromkeys(), Таким образом, чтобы установить все значенияTrueиспользоватьdict.fromkeys(range(5), True), Берегись, значениене копируется, так что вы можете избежать этого, когда у вас есть изменяемое значение; Это'Буду делиться между всеми ключами. Martijn Pieters
Примечание: ключи также могут быть результатом метода:{ n*2 : n for n in range(3) } => {0: 0, 2: 1, 4: 2}, И то, и другое можно сделать в одном выражении:{ n*2 : n*3 for n in range(3) } => { 0: 0, 2: 3, 4: 6 } Zaaier
FWIW,dict.update также может принимать итерацию пар ключ-значение, какdict конструктор mgilson

Похожие вопросы