2013-01-24 11 views
289

Pythonで辞書の理解を(キーのために)作成することは可能ですか?私たちは、リスト内包にこれを短縮することができますPython Dictionary Comprehension

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

l = [n for n in range(1, 11)]リストの内包表記なし

は、あなたはこのようなものを使用することができます。

しかし、辞書のキーを同じ値に設定したいとします。 私が行うことができます。

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

私はこれを試してみた:

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

しかし、私はforSyntaxErrorを取得します。

また

(私はこの部分が必要ですが、思っていない)、あなたはこのように、異なる値の束に辞書のキーを設定することができます

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)] 

これもforSyntaxErrorを発生させます。

+1

将来の読者のために:NumPy配列を使用すると、複数の要素を単一の値または値のリストに設定できます。 NumPyを使用する理由がまだない場合は、この機能のためだけに価値がないかもしれません。 –

答えて

390

dictionary comprehensions in 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} 

は、既存の辞書には、一度に複数のキーを設定する方法です。そのための直接のショートカットはありません。既に示したようにループするか、辞書の理解を使って新しい値で新しい辞書を作成し、oldDict.update(newDict)を実行して新しい値を古い辞書にマージすることができます。

+10

FWIW、 'dict.update'は、' dict'コンストラクタのように、キーと値のペアの繰り返し可能性を受け入れることもできます。 – mgilson

+1

すべての値が同じ辞書を作成する場合は、 'dict.fromkeys()'を使用してください。したがって、すべての値を 'True'に設定するには' dict.fromkeys(range(5)、True) 'を使います。注意してください、値はコピーされません*ので、あなたは値を変更可能な場合はこれを避けることができます。すべてのキー間で共有されます。 –

+1

注:キーはメソッドの結果でもあります: '{n * 2:nの範囲指定(3)} => {0:0,2:1,4:2}'です。どちらも同じ式で実行できます: '{3 *} n = 3 {0:0、2:3、4:6}'のnに対しては{n * 2:n * 3}。 – Zaaier

136

あなたは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} 

これは、すべてのキーが同じ値にマッピングする辞書を作成する最速の方法です。

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

:あなたが実際に defaultdictは、同様に有用であるかもしれない、すべてのキーを初期化するを必要としない場合

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

を:

はしかし、可変オブジェクトでこれを使用して注意してください

2番目の部分に答えるには、必要なものだけを補完する必要があります。

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

かのpython2.6 0:あなたは__missing__をオーバーライドする場合

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

またdefaultdictのようにやや働く辞書の巧妙なサブクラスを作成することができます。

>>> 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) 
{} 

ニート。

+0

'd = defaultdict(lambda:True)'の場合、ラムダは必須ではないことに注意してください。 – rhbvkleef

21
>>> {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} 
10

使用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))]) 
+10

副作用として、これは 'd = dict(zip(i_s、x_s)) 'と同じことです – mgilson

-2

あなたがハッシュすることはできませんので、長い間、彼らは同じ長さであるとして、あなたは、各リストで任意の値を持つことができるようになりますそのようなリスト。 代わりにこれを試してみてください、それは

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

これはOPが望んでいたことを全くしません... –

6

タプルを使用して、リストの内包表記の主な目的は、元のリストを変更したり、破壊することなく別のものに基づいて、新しいリストを作成することです。

代わりの

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

または

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

を書いて、あなたがそれを反復、新しいリストを作成している2つのトップのコードブロックでのみ

l = range(1, 11) 

を書く必要がありますそれぞれの要素を返すだけです。それはリストコピーを作成するだけの高価な方法です。

これを行う、別の辞書に基づいて、同じ値に設定されたすべてのキーを使用して新しい辞書を取得するには:

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)のi"を有効なキーではない、それは単なる構文エラーです。 dictsキーとしてリストをサポートしている場合、あなたは

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

なく

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

ような何かをするだろうが、リストはハッシュ可能ではありませんので、あなたは、dictのキーとしてそれらを使用することはできません。

16

私は本当に@mgilsonのコメントが好きです。あなたは2つのiterables、1つはキーと他の値に対応しているので、次のこともできます。

D = { '' 3:1、 'B':2 'C'}与え

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

単語の発生をカウントするこの例を考え

9

をリストに

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} 
+0

これは面白いですが、あなたは「こんにちは」のような鍵を何度も数えているので – FuriousGeorge