Słownik Pythona

Czy jest możliwe stworzenie słownika w Pythonie (dla kluczy)?

Bez kompilacji list, możesz użyć czegoś takiego:

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

Możemy to skrócić do zrozumienia listy: l = [n for n in range(1, 11)].

Powiedzmy jednak, że chcę ustawić klucze słownika na tę samą wartość. Mogę zrobić:

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

Próbowałem tego:

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

Jednak dostaję SyntaxError na for.

W dodatku (nie potrzebuję tej części, ale tylko się zastanawiam), możesz Ustaw klucze słownika na kilka różnych wartości, takich jak:

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

Czy jest to możliwe ze słownikowym zrozumieniem?

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

To również podnosi SyntaxError na for.

Author: Kevin Guan, 2013-01-24

8 answers

W Pythonie 2.7+istnieją składnia słowników , ale nie działają one tak, jak próbujesz. Podobnie jak rozumienie listy, tworzą one Nowy słownik ; nie można ich używać do dodawania kluczy do istniejącego słownika. Ponadto musisz określić klucze i wartości, chociaż oczywiście możesz określić wartość fałszywą, jeśli chcesz.

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

Jeśli chcesz ustawić je wszystkie Na True:

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

Wygląda na to, że prosisz o sposób ustawienia wielu kluczy naraz istniejący słownik. Nie ma na to bezpośredniego skrótu. Możesz albo zapętlić tak, jak już pokazałeś, albo użyć rozumienia słownika, aby utworzyć nowy dict z nowymi wartościami, a następnie wykonać oldDict.update(newDict), aby połączyć nowe wartości ze starym dict.

 435
Author: BrenBarn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-09 03:59:36

Możesz użyć metody klasy dict.fromkeys...

>>> dict.fromkeys(range(1, 11), True)
{1: True, 2: True, 3: True, 4: True, 5: True, 6: True, 7: True, 8: True, 9: True, 10: True}

Jest to najszybszy sposób na stworzenie słownika, w którym wszystkie klawisze mapują tę samą wartość.

Bądź ostrożny używając tego z mutowalnymi obiektami:

d = dict.fromkeys(range(10), [])
d[1].append(2)
print(d[2])  # ???

Jeśli faktycznie nie potrzebujesz, aby zainicjować wszystkie klucze, a defaultdict może być również przydatny:

from collections import defaultdict
d = defaultdict(lambda: True)

Aby odpowiedzieć na drugą część, rozumienie dict jest właśnie tym, czego potrzebujesz:

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

Lub dla python2. 6:

dict((k, k) for k in range(10))

Możesz również stworzyć sprytną podklasę dict, która działa nieco jak defaultdict, jeśli nadpisasz __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)
{}
/ Align = "left" / Neat
 141
Author: mgilson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-28 14:44:04
>>> {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}
 23
Author: NPE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-24 17:55:37

Bardzo podoba mi się komentarz @ mgilson, ponieważ jeśli masz dwie iterable, jedna odpowiadająca kluczom, a druga wartościom, możesz również wykonać następujące czynności.

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

Dawanie

D = {"a": 1, "b": 2, "c": 3}

 19
Author: ehontz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-16 18:03:34

Użyj dict () na liście krotek, To rozwiązanie pozwoli Ci mieć dowolne wartości w każdej liście, o ile są one tej samej długości

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))])
 11
Author: Bryan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-24 17:55:26

Rozważ ten przykład zliczania występowania słów na liście za pomocą rozumienia słownikowego

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

A wynikiem jest

{'again': 1, 'hi': 1, 'hello': 3, 'today': 1, 'morning': 1}
 10
Author: adonese,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-17 19:51:40

Głównym celem zrozumienia listy jest stworzenie nowej listy opartej na innej bez zmiany lub zniszczenia oryginalnej listy.

Zamiast pisać

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

Lub

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

Powinieneś pisać tylko

    l = range(1, 11)

W dwóch najwyższych blokach kodu tworzysz nową listę, powtarzając ją i zwracając każdy element. To tylko drogi sposób tworzenia kopii listy.

Aby uzyskać nowy słownik ze wszystkimi kluczami ustawionymi na tę samą wartość na podstawie kolejny dict, zrób to:

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

Otrzymujesz SyntaxError, ponieważ gdy piszesz

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

W zasadzie mówisz: "Ustaw mój klucz 'i for i in range(1, 11)' na True" I "I for i in range(1, 11)" nie jest poprawnym kluczem, to tylko błąd składni. Jeśli dicts obsługuje listy jako klucze, zrobisz coś w stylu

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

I nie

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

Ale Listy nie są hashowalne, więc nie możesz ich używać jako kluczy dict.

 7
Author: Bonifacio2,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-24 18:53:48

Nie możesz tak hashować listy. spróbuj tego zamiast tego, używa krotek

d[tuple([i for i in range(1,11)])] = True
 -3
Author: Aditya Sihag,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-24 17:58:12