2017-06-07 8 views
2

上記が可能かどうかを知りたいと思います。私は現在、辞書のリストを持っています(リスト内の辞書の数は無骨です)。リストから辞書を別の辞書にコピーする必要があります。これは私のHTTP投稿要求のペイロードになります。下の例では、これをより明確にする必要があります。dictとキー/値の組の組み合わせを構築する

myList = [{'updates[123]': '1'}, {'updates[234]': '2'}, {'updates[345]': '3'}] 

次に、別のdictにコピーする必要があります。

payload = { 
    'updates[123]': '1', 
    'updates[234]': '2', 
    'updates[345]': '3' 
    } 

は、それが元のリストの要素数を知らないあなたの「ペイロード」辞書を作成することは可能ですか、単に持っている唯一の方法は、正しいインデックスにそれがためにlen(myList)をチェックする他の例場合であります何度か?

はあなたに

答えて

7

だけループを感謝し、辞書を兼ね備え:

payload = {} 
for d in myList: 
    payload.update(d) 

または単一のdictの理解使用して:

payload = {k: v for d in myList for k, v in d.items()} 

やジェネレータ式とdict()を使用して:

payload = dict(kv for d in myList for kv in d.items()) 

またはfunctools.reduce()を使用して:辞書リストの最後の勝利からのすべての場合において

from functools import reduce 

payload = reduce(lambda d1, d2: d1.update(d2) or d1, myList, {}) 

、重複キーがある場合は、キーと値。

性能比較:

>>> import timeit 
>>> from functools import reduce 
>>> from random import choice, randint 
>>> from string import ascii_letters 
>>> testdata = [ 
...  {''.join([choice(ascii_letters) for _ in range(randint(10, 25))]): None 
...  for _ in range(randint(1, 5))} for _ in range(100)] 
>>> def loop(myList): 
...  payload = {} 
...  for d in myList: 
...   payload.update(d) 
... 
>>> def dictcomp(myList): 
...  {k: v for d in myList for k, v in d.items()} 
... 
>>> def genexpr(myList): 
...  {k: v for d in myList for k, v in d.items()} 
... 
>>> def with_reduce(myList, _reduce=reduce): 
...  _reduce(lambda d1, d2: d1.update(d2) or d1, myList, {}) 
... 
>>> def trial(f, testdata): 
...  t = timeit.Timer('f(l)', globals={'f': f, 'l': testdata}) 
...  loops, time = t.autorange() 
...  print(f'{f.__name__:>12}: {(time/loops) * 1000000:0.1f} µs') 
... 
>>> for f in (loop, dictcomp, genexpr, with_reduce): 
...  trial(f, testdata) 
... 
     loop: 24.6 µs 
    dictcomp: 34.7 µs 
    genexpr: 35.6 µs 
with_reduce: 35.2 µs 

すべてのオプションのだから、簡単なforループが最も効率的です。

関連する問題