创建字典的更优雅代码的提示

j36*_*701 3 python dictionary for-loop

我正在使用列表中的键和值创建字典:

keys = ['Ptot', 'P1', 'P2', 'P3', 'Q1', 'Q2', 'Q3']
val = ['max', 'first', 'first', 'first', 'first', 'first', 'first']
Run Code Online (Sandbox Code Playgroud)

我可以通过以下方式手动创建字典:

dictionary = {'Ptot': 'max', 'P1': 'first', 'P2': 'first', 'P3': 'first', 'Q1': 'first', 'Q2': 'first', 'Q3': 'first'}
Run Code Online (Sandbox Code Playgroud)

如何通过for循环从列表中更优雅地创建字典?我的问题是列表的大小比此示例大得多。

Ayx*_*xan 11

看一下zip

>>> d = dict(zip(keys, val))
>>> d
{'Ptot': 'max', 'P1': 'first', 'P2': 'first', 'P3': 'first', 'Q1': 'first', 'Q2': 'first', 'Q3': 'first'}
Run Code Online (Sandbox Code Playgroud)

创建一个迭代器,以聚合每个可迭代对象中的元素。

返回一个元组的迭代器,其中第i个元组包含每个参数序列或可迭代对象中的第i个元素。

然后,我们将返回值传递dict给创建字典。这可能比简单的循环更有效,因为内建函数在Python中以C速度运行,并且实现者可能有更多时间对其进行优化。


Dev*_*ngh 6

使用字典理解,您可以在遍历它们的keys同时从and val列表中选择键和值,并且为了安全起见,如果keysand val的长度不相等,您可以通过itertools.zip_longest将它们全部压缩在一起。创建最长子序列的迭代器,确保说keys的长于val,我们没有它们的键,也许将来可以重新分配它们(谢谢@quamrana)

from itertools import zip_longest
keys = ['Ptot', 'P1', 'P2', 'P3', 'Q1', 'Q2', 'Q3']
val = ['max', 'first', 'first', 'first', 'first', 'first', 'first']

print({k:v for k,v in zip_longest(keys, val)})
Run Code Online (Sandbox Code Playgroud)

输出是

{'Ptot': 'max', 'P1': 'first', 'P2': 'first', 'P3': 'first', 'Q1': 'first', 'Q2': 'first', 'Q3': 'first'}
Run Code Online (Sandbox Code Playgroud)

的更大的长度的一个例子keys,然后val

from itertools import zip_longest
keys = ['Ptot', 'P1', 'P2', 'P3', 'Q1', 'Q2', 'Q3', 'QX', 'QY']
val = ['max', 'first', 'first', 'first', 'first', 'first', 'first']

print({k:v for k,v in zip_longest(keys, val)})
Run Code Online (Sandbox Code Playgroud)

输出将是

{'Ptot': 'max', 'P1': 'first', 'P2': 'first', 
'P3': 'first', 'Q1': 'first', 'Q2': 'first', 'Q3': 'first', 
'QX': None, 'QY': None}
Run Code Online (Sandbox Code Playgroud)

因此,我们看到密钥并没有在这里丢失,而是被使用并且将值设置为None,但是使用zip会导致我们丢失那些密钥!

但是,如果我们只想从较小的列表中选择元素,则可以执行以下操作(感谢@MitchelPaulin)

from itertools import zip_longest
keys = ['Ptot', 'P1', 'P2', 'P3', 'Q1', 'Q2', 'Q3', 'QX', 'QY']
val = ['max', 'first', 'first', 'first', 'first', 'first', 'first']

#Pick the smaller of the 2 lengths and iterate only on those indexes
length = min(len(keys), len(val))
print({keys[idx]:val[idx] for idx in range(length)})
Run Code Online (Sandbox Code Playgroud)

  • 为了安全起见,可能要使用`min(len(keys),len(val))` (2认同)
  • 您可以将“ keys”和“ vals”一起压缩在一起。 (2认同)