Python中,如何合并两个键相同,值为元祖类型的字典?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python中,如何合并两个键相同,值为元祖类型的字典?相关的知识,希望对你有一定的参考价值。
dicxs="李明":("男",19), "杨柳":("女",18), "张一凡":("男",18), "许可":("女",20), "王小小":("女",19), "陈心":("女",19)
diccj="李明": (78,89,90), "杨柳": (51,89,56), "张一凡": (82,90,96),"许可": (93,90,98), "王小小": (69,89,91), "陈心": (50,85,68)
C =
for key in list(set(dicxs) | set(diccj)):
if dicxs.get(key) and diccj.get(key):
C[key]= list(dicxs[key])+list(diccj[key])
elif dicxs.get(key):
C[key]=list(dicxs[key])
else:
C[key]=list(diccj[key]) 参考技术A 那你要怎么合并两个元组呢?追问
合并成 dicxscj="李明":("男",19,78,89,90)。。。。。。。。这样的
追答dicxscj = k: v + diccj[k] for k, v in dicxs.items() if k in diccj
结果为两个字典的交集
如何合并两个 STL 映射?
【中文标题】如何合并两个 STL 映射?【英文标题】:How can I merge two STL maps? 【发布时间】:2011-04-08 01:44:47 【问题描述】:如何将两个 STL 映射合并为一个?它们都具有相同的键和值类型 (map<string, string>
)。如果键重叠,我想优先选择其中一张地图。
【问题讨论】:
【参考方案1】:假设你想保留mapA
中的元素,并合并mapB
中mapA
中没有key的元素:
mapA.insert(mapB.begin(), mapB.end())
我想你会做你想做的。
(编辑:如果您使用的是 C++17 或更高版本,请考虑以下答案:https://***.com/a/56594603/118150)
工作示例:
#include <iostream>
#include <map>
void printIt(std::map<int,int> m)
for(std::map<int,int>::iterator it=m.begin();it!=m.end();++it)
std::cout << it->first<<":"<<it->second<<" ";
std::cout << "\n";
int main()
std::map<int,int> foo,bar;
foo[1] = 11; foo[2] = 12; foo[3] = 13;
bar[2] = 20; bar[3] = 30; bar[4] = 40;
printIt(foo);
printIt(bar);
foo.insert(bar.begin(),bar.end());
printIt(foo);
return 0;
输出:
:!./insert
1:11 2:12 3:13
2:20 3:30 4:40
1:11 2:12 3:13 4:40
【讨论】:
如果键匹配,我看不出这不会覆盖 mapA 中的重复项。如果我只是说 mapB 是我的“首选”地图,我认为我可以使用它。这样,如果它是重复的,那么 mapB 中的键将是最终在新地图(现在是 mapA)中结束的那个。这听起来是正确的还是我误解了当有重复 E 时插入的作用? Insert 不会覆盖已有的元素,当key发生冲突时,已经存在的元素优先。 这有多复杂?是否为 n log(n),其中 n 是源映射中的元素数。还是可以降低复杂度(合并两棵红黑树)? 标准说复杂度是 n log(n)(来源:cppreference) @galinette 不完全是,它是 O(n log(n+m)) 其中 n 是源范围的大小(在这种情况下,实际上是源映射的大小),而 m是目标地图的大小。 (在源范围按目标的value_comp()
排序的特殊情况下,它可以实现为 O(n (1 + log(m/(1+n))) + log(m)),但是标准没有强制要求。)【参考方案2】:
C++17
如John Perry's answer 中所述,由于C++17 std::map
提供了merge()
成员函数。 merge()
函数基于使用 insert()
为目标映射生成与 jkerian's solution 相同的结果,正如您从以下示例中看到的那样,我从 jkerian 借来的。我刚刚用C++11 和C++17 的一些特性更新了代码(例如using
type alias、range-based for loop 和structured binding 和list initialization):
using mymap = std::map<int, int>;
void printIt(const mymap& m)
for (auto const &[k, v] : m)
std::cout << k << ":" << v << " ";
std::cout << std::endl;
int main()
mymap foo 1, 11, 2, 12, 3, 13 ;
mymap bar 2, 20, 3, 30, 4, 40 ;
printIt(foo);
printIt(bar);
foo.merge(bar);
printIt(foo);
return 0;
输出:
1:11 2:12 3:13 2:20 3:30 4:40 1:11 2:12 3:13 4:40
如您所见,merge()
在键重叠时也会优先考虑目标映射foo
。如果你想反过来,那么你必须打电话给bar.merge(foo);
。
但是,使用insert()
和merge()
对源映射的影响有所不同。 insert()
函数将新条目添加到目标映射中,而 merge()
将条目从源映射中移出。这意味着对于上面的示例,insert()
不会改变bar
,但merge()
从bar
中删除4:40
,因此只有2:20
和3:30
保留在bar
中。
注意:为了简洁起见,我重用了 jkerian 中使用 map<int, int>
的示例,但 merge()
也适用于您的 map<string, string>
。
Code on Coliru
【讨论】:
【参考方案3】:请注意,从 C++17 开始,有一个用于映射的 merge()
方法。
【讨论】:
【参考方案4】:根据 ISO/IEC 14882:2003,第 23.1.2 节,表 69,表达式 a.insert(i,j):
pre: i,j 不是 a 的迭代器。插入范围内的每个元素 [i, j) 当且仅当没有元素的键等价于 具有唯一键的容器中该元素的键;
由于 std::map 必须遵循这个限制,如果你想优先考虑一个映射中的“值”而不是另一个映射,你应该插入它。例如,
std::map<int, int> goodKeys;
std::map<int, int> betterKeys;
betterKeys.insert(goodKeys.begin(), goodKeys.end());
所以如果 goodKeys 和 betterKeys 中有任何等价的键,betterKeys 的“值”会被保留。
【讨论】:
【参考方案5】:如果你想将条目从一张地图复制到另一张地图,你可以使用std::map
的insert
:
targetMap.insert(sourceMap.begin(), sourceMap.end());
但请注意,insert
如果元素的键已经在 targetMap 中,则不会更新元素;这些项目将保持原样。要覆盖元素,您必须显式复制,例如:
for(auto& it : sourceMap)
targetMap[it.first] = it.second;
如果您不介意丢失sourceMap
中的数据,另一种实现复制和覆盖的方法是将insert
目标放入源并将std::swap
结果:
sourceMap.insert(targetMap.begin(), targetMap.end());
std::swap(sourceMap, targetMap);
交换后,sourceMap
将包含 targetMap
的旧数据,targetMap
将是两个映射的合并,优先考虑 sourceMap
的条目。
【讨论】:
以上是关于Python中,如何合并两个键相同,值为元祖类型的字典?的主要内容,如果未能解决你的问题,请参考以下文章
Python列表元素为字典时,如何根据其中某个相同的键值进行元素合并