我有两本词典:
x = [{'policy': 'a-b-windows2007', 'starttime': '4', 'duration': '5'},
{'policy': 'ab-server2012', 'starttime': '4', 'duration': '5'},
{'policy': 'Aa-windows', 'starttime': '4', 'duration': '5'}]
y = [{'policy': 'Windws a-b-windows2007', 'total_hosts': '160'},
{'policy': 'Windows ab-server2012', 'total_hosts': '170'},
{'policy': 'Windows Aa-windows', 'total_hosts': '180'}]
如果y中的政策是x =策略,我希望通过组合x和y来得到一个dict。我创建了正则表达式,我正在努力如何合并它们
x和y的长度不一样。
到目前为止我的尝试:
for key in x:
for keys in y:
if key['policy'] == re.match('[0-9]+|\b[a-z-]+(\d)',keys['policy']):
z.update(y)
通缉输出:
z=[{policy: 'a-b-windows2007',starttime: '4', duration: '5',total_hosts:'160'},
{policy: 'ab-server2012',starttime: '4', duration: '5',total_hosts:'170'},
{policy: 'Aa-windows',starttime: '4', duration: '5',total_hosts:'180'}]
答案 0 :(得分:2)
你的正则表达式对我不起作用,这是一个嵌套的for循环解决方案假设你的policy
如下:这个格式<windows> <version_number>
我们拆分策略值并把version_number进行比较,你可以如果您愿意,也可以轻松将其转换为字典理解。
x = [{'policy': 'a-b-windows2007', 'starttime': '4', 'duration': '5'},
{'policy': 'ab-server2012', 'starttime': '4', 'duration': '5'},
{'policy': 'Aa-windows', 'starttime': '4', 'duration': '5'}]
y = [{'policy': 'Windows a-b-windows2007', 'total_hosts': '160'},
{'policy': 'Windows ab-server2012', 'total_hosts': '170'},
{'policy': 'Windows Aa-windows', 'total_hosts': '180'}]
for x_dict in x:
for y_dict in y:
if x_dict['policy'] == y_dict['policy'].split(' ')[1]:
if "total_hosts" in x_dict:
x_dict["total_hosts"].append(y_dict["total_hosts"])
else:
x_dict["total_hosts"] = y_dict["total_hosts"]
print(x)
给出:
[{'starttime': '4', 'duration': '5', 'policy': 'a-b-windows2007', 'total_hosts': '160'},
{'starttime': '4', 'duration': '5', 'policy': 'ab-server2012', 'total_hosts': '170'},
{'starttime': '4', 'duration': '5', 'policy': 'Aa-windows', 'total_hosts': '180'}]
这个解决方案更新了x list
所以如果你想要一个新的列表而不改变x,只需复制一个x就可以改变名为z并更改for循环,其中x将其变为z ...... / p>
答案 1 :(得分:1)
试试这个。
merge_dicts
是here中必不可少的恶意。
我认为Windws
是错误的。否则,您必须指定连接条件更清晰。
将y
转换为索引字典会比嵌套for循环产生更好的性能提升。
def merge_dicts(x, y):
z = x.copy()
z.update(y)
return z
y_indexed = {e['policy']: e for e in y}
joined = [
merge_dicts(y_indexed['Windows ' + e['policy']], e)
for e in x]
如果你有很多这样的dict
,请考虑使用pandas。
答案 2 :(得分:1)
在这种特殊情况下,你真的不需要正则表达式;但修改代码以包含一个代码并不难。
你可以做类似的事情:
l=[]
for xItem in x:
for yItem in y:
if yItem['policy'].endswith(xItem['policy']):
tmpItem=xItem
tmpItem['total_hosts'] = yItem['total_hosts']
l.append(tmpItem)
效率有点低,但事先对列表进行排序会有所帮助,但前提是列表足够大,以便排序时间能够分摊。
答案 3 :(得分:0)
这假设列表长度相同,x
中的每个元素都在y
中有相应的元素。
对列表进行排序,以便匹配的词典共享一个索引,然后将zip
两者放在一起。使用itertools.chain
将它们提供给dict
构造函数。
import itertools
x.sort(key=lambda x: x['policy'])
y.sort(key=lambda x: x['policy'])
z = [dict(itertools.chain(a.items(), b.items())) for a, b in zip(x, y)]
我认为在更新版本的python上你可以dict(**a, **b)
,但我在这台电脑上使用3.3,所以我不能确定。
另一种方法是将y
(没有重复政策的列表)转换为字典。
y_dict = {d['policy'].split()[-1]: d for d in y}
.split()[-1]
将为我们提供政策条目的最后一句话。然后我们可以通过x来构建我们的新列表。
z = []
for d in x:
new_dict = {k:v for k,v in d.items()}
new_dict.update({k:v for k, v in y_dict[d['policy']] if k != 'policy'})
z.append(new_dict)
答案 4 :(得分:0)
在您的示例中,endswith
方法比正则表达式更简单(并且可能更强大)。
z = {}
for key in x:
print(key['policy'])
for keys in y:
print(keys['policy'])
if keys['policy'].endswith(key['policy']):
kz = key.copy() # copy to avoid any change in x
kz['total_hosts'] = keys['total_hosts']
z.append(kz)