Python字典由当前表达式组合

时间:2016-11-15 14:28:12

标签: python dictionary

我有两本词典:

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'}] 

5 个答案:

答案 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_dictshere中必不可少的恶意。

我认为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)