我想知道上述情况是否可行.我目前有一个字典列表(列表中的字典数是arbritary).我将不得不将列表中的字典"复制"到另一个字典中,该字典将成为我的HTTP post请求的有效负载.下面的例子应该更清楚:
myList = [{'updates[123]': '1'}, {'updates[234]': '2'}, {'updates[345]': '3'}]
Run Code Online (Sandbox Code Playgroud)
然后我需要将它复制到另一个词典中.
payload = {
'updates[123]': '1',
'updates[234]': '2',
'updates[345]': '3'
}
Run Code Online (Sandbox Code Playgroud)
是否有可能创建"有效载荷"字典而不知道原始列表中的元素数量,或者是否只有在其他情况下检查len(myList)以便索引正确的次数的唯一方法?
谢谢
只需循环并组合字典:
payload = {}
for d in myList:
payload.update(d)
Run Code Online (Sandbox Code Playgroud)
或使用单一词典理解:
payload = {k: v for d in myList for k, v in d.items()}
Run Code Online (Sandbox Code Playgroud)
或使用生成器表达式和dict():
payload = dict(kv for d in myList for kv in d.items())
Run Code Online (Sandbox Code Playgroud)
或使用functools.reduce():
from functools import reduce
payload = reduce(lambda d1, d2: d1.update(d2) or d1, myList, {})
Run Code Online (Sandbox Code Playgroud)
在所有情况下,如果存在重复键,则最后列出的字典中的键值将获胜.
表现比较:
>>> 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
Run Code Online (Sandbox Code Playgroud)
因此,在所有选项中,简单for循环是最有效的.