合并两个项目互换的字典
Merging two dictionaries where items are interchanged
假设我有字典:
dict1 = {'A': 1, 'B': 2, 'C' : 3}
dict2 = {'a': 4, 'b': 5, 'c' : 6}
This link 提出了几种合并两者的方法,但所有合并都是简单的串联。我想像经销商洗牌一样合并它们,或者像拉链一样合并它们。我的意思是一旦合并 dict1
和 dict2
,结果 dict3
应该变成
dict3 = {'A': 1, 'a': 4, 'B': 2, 'b': 5, 'C' : 3, 'c' : 6}
因此合并以交替方式从 dict1
和 dict2
抓取元素。我的词典实际上非常大,因此无法手动进行。
有 round-robin itertools
方法 select 数据。
您可以使用:
dict3 = dict(roundrobin(dict1.items(), dict2.items()))
输出:
{'A': 1, 'a': 4, 'B': 2, 'b': 5, 'C': 3, 'c': 6}
from itertools import cycle, islice
def roundrobin(*iterables):
"roundrobin('ABC', 'D', 'EF') --> A D E B F C"
# Recipe credited to George Sakkis
num_active = len(iterables)
nexts = cycle(iter(it).__next__ for it in iterables)
while num_active:
try:
for next in nexts:
yield next()
except StopIteration:
# Remove the iterator we just exhausted from the cycle.
num_active -= 1
nexts = cycle(islice(nexts, num_active))
您也可以使用more-itertools.interleave
from more_itertools import interleave
dict(interleave(dict1.items(), dict2.items()))
为了便于阅读而缩进:
from itertools import chain
dict(
chain.from_iterable(
zip(dict1.items(), dict2.items())
)
)
如果不能保证您的词典大小相同,请调整此解决方案以使用 itertools.zip_longest()
而不是基本的 zip()
这种方法有很多地方可能出错。如果您的 2 部词典长度不同怎么办?如果他们有重复的钥匙怎么办?如果以后您需要 3 个字典而不是 2 个怎么办?
此外,您是否有此要求背后的真实用例?你真的需要像这样用所有数据构建一个新的字典,还是只需要像这样以特定的替代方式迭代(键,值)对?
假设你不必担心上面的问题,如果你只需要迭代,你可以简单地做这样的事情:
def iter_zip(dict1, dict2):
for i1, i2 in zip(dict1.items(), dict2.items()):
yield i1
yield i2
dict1 = {'A': 1, 'B': 2, 'C' : 3}
dict2 = {'a': 4, 'b': 5, 'c' : 6}
# you can then do
for key, val in iter_zip(dict1, dict2):
do_something(key, val)
如果你真的需要建立一个新的字典,现在很简单:
dict(iter_zip(dict1, dict2))
# {'A': 1, 'a': 4, 'B': 2, 'b': 5, 'C': 3, 'c': 6}
假设我有字典:
dict1 = {'A': 1, 'B': 2, 'C' : 3}
dict2 = {'a': 4, 'b': 5, 'c' : 6}
This link 提出了几种合并两者的方法,但所有合并都是简单的串联。我想像经销商洗牌一样合并它们,或者像拉链一样合并它们。我的意思是一旦合并 dict1
和 dict2
,结果 dict3
应该变成
dict3 = {'A': 1, 'a': 4, 'B': 2, 'b': 5, 'C' : 3, 'c' : 6}
因此合并以交替方式从 dict1
和 dict2
抓取元素。我的词典实际上非常大,因此无法手动进行。
有 round-robin itertools
方法 select 数据。
您可以使用:
dict3 = dict(roundrobin(dict1.items(), dict2.items()))
输出:
{'A': 1, 'a': 4, 'B': 2, 'b': 5, 'C': 3, 'c': 6}
from itertools import cycle, islice
def roundrobin(*iterables):
"roundrobin('ABC', 'D', 'EF') --> A D E B F C"
# Recipe credited to George Sakkis
num_active = len(iterables)
nexts = cycle(iter(it).__next__ for it in iterables)
while num_active:
try:
for next in nexts:
yield next()
except StopIteration:
# Remove the iterator we just exhausted from the cycle.
num_active -= 1
nexts = cycle(islice(nexts, num_active))
您也可以使用more-itertools.interleave
from more_itertools import interleave
dict(interleave(dict1.items(), dict2.items()))
为了便于阅读而缩进:
from itertools import chain
dict(
chain.from_iterable(
zip(dict1.items(), dict2.items())
)
)
如果不能保证您的词典大小相同,请调整此解决方案以使用 itertools.zip_longest()
而不是基本的 zip()
这种方法有很多地方可能出错。如果您的 2 部词典长度不同怎么办?如果他们有重复的钥匙怎么办?如果以后您需要 3 个字典而不是 2 个怎么办?
此外,您是否有此要求背后的真实用例?你真的需要像这样用所有数据构建一个新的字典,还是只需要像这样以特定的替代方式迭代(键,值)对?
假设你不必担心上面的问题,如果你只需要迭代,你可以简单地做这样的事情:
def iter_zip(dict1, dict2):
for i1, i2 in zip(dict1.items(), dict2.items()):
yield i1
yield i2
dict1 = {'A': 1, 'B': 2, 'C' : 3}
dict2 = {'a': 4, 'b': 5, 'c' : 6}
# you can then do
for key, val in iter_zip(dict1, dict2):
do_something(key, val)
如果你真的需要建立一个新的字典,现在很简单:
dict(iter_zip(dict1, dict2))
# {'A': 1, 'a': 4, 'B': 2, 'b': 5, 'C': 3, 'c': 6}