我正在从只有2个键的大列表中创建字典的子列表。我的数据是这样的:
[{'query_name': 'google.com', 'ip4_address': '1.1.1.1' } , {'query_name': 'google.com','ip4_address': '2.2.2.2'}, {'query_name': 'google.com', 'ip4_address': '3.3.3.3'}]
我想找出特定“ query_name”的“ ip4_address”的唯一出现次数,并将所有“ ip4_address”合并到单个字典中
输出示例:
['query_name': 'google.com', 'ip4_address': '1.1.1.1' ,'2.2.2.2', '3.3.3.3', 'count': '3' }]
这是我的代码:
reader = DataFileReader(open((os.path.join('active_dns', filename)), "rb"), DatumReader())
for user in reader:
keys = ['query_name', ,'ip4_address']
all_values =dict((key, user[key]) for key in keys)
a_lst.append(all_values)
到目前为止,我已经尝试过将两个键进行比较并使计数器递增以获取重复值:
counterdict = defaultdict(list)
for d in a_lst:
counterdict[d['ip4_address']][d['query_name']] += 1
但是到目前为止没有期望的结果。任何帮助表示赞赏。
答案 0 :(得分:2)
您可以使用以下方法获得所需的结果:
from collections import defaultdict
a_lst=[{'query_name': 'google.com', 'ip4_address': '1.1.1.1' } ,
{'query_name': 'google.com','ip4_address': '2.2.2.2'}, {'query_name':
'google.com', 'ip4_address': '3.3.3.3'},{'query_name': 'yahoo.com',
'ip4_address': '3.3.3.3'}]
query_dict=defaultdict(set)
for d in a_lst:
query_dict[d['query_name']].add(d['ip4_address'])
counterlist = []
for q in query_dict:
cdict={}
cdict['query_name'] = q
cdict['ip4_address'] = list(query_dict[q])
cdict['count'] = len(cdict['ip4_address'])
counterlist.append(cdict)
print(counterlist)
输出为:
[{'query_name': 'google.com', 'ip4_address': ['3.3.3.3', '2.2.2.2', '1.1.1.1'], 'count': 3}, {'query_name': 'yahoo.com', 'ip4_address': ['3.3.3.3'], 'count': 1}]
答案 1 :(得分:0)
因此,可以通过使用itertools.groupby
来实现。需要注意的是,必须对数据进行预排序才能使其正常工作。
from itertools import groupby
from operator import itemgetter
data = [{'query_name': 'google.com', 'ip4_address': '1.1.1.1' } , {'query_name': 'google.com','ip4_address': '2.2.2.2'}, {'query_name': 'google.com', 'ip4_address': '3.3.3.3'}, {'query_name': 'google.com', 'ip4_address': '1.1.1.1' }, {'query_name': 'google.com', 'ip4_address': '1.1.1.1' }]
query = itemgetter('query_name')
ip = itemgetter('ip4_address')
def custom_sort(obj):
q = query(obj)
i = ip(obj)
return (q, i)
for k, v in groupby(sorted(data, key=custom_sort), key=custom_sort):
base = {'query_name': k[0], 'ip4_address': k[1]}
base.update({'count': len(list(v))})
print(base)
{'query_name': 'google.com', 'ip4_address': '1.1.1.1', 'count': 3}
{'query_name': 'google.com', 'ip4_address': '2.2.2.2', 'count': 1}
{'query_name': 'google.com', 'ip4_address': '3.3.3.3', 'count': 1}
答案 2 :(得分:0)
您可以使用熊猫轻松地做到这一点。
import pandas as pd
l = [{'query_name': 'google.com', 'ip4_address': '1.1.1.1' } , {'query_name': 'google.com','ip4_address': '2.2.2.2'}, {'query_name': 'google.com', 'ip4_address': '3.3.3.3'},{'query_name': 'yahoo.com', 'ip4_address': '1.1.1.2' }]
df = pd.DataFrame(l)
ips=df.groupby(by='query_name')['ip4_address'].value_counts()
ip_dict=ips.to_dict()
答案 3 :(得分:0)
这是另一种方法。
data = [{'query_name': 'google.com', 'ip4_address': '1.1.1.1'},
{'query_name': 'google.com', 'ip4_address': '2.2.2.2'},
{'query_name': 'google.com', 'ip4_address': '3.3.3.3'}]
def get_ip4(data_list, query_name):
return { x["ip4_address"] for x in data_list if x["query_name"]==query_name }
query_name = "google.com"
my_desired_output = {k: v for k, v in
zip(['query_name', 'ip4_address', 'count'],
[query_name, list(get_ip4(data, query_name)), len(list(get_ip4(data, query_name)))])}
答案 4 :(得分:0)
嗯,“鼻子上的”解决方案怎么样?
data = [
{'query_name': 'google.com', 'ip4_address': '1.1.1.1'},
{'query_name': 'google.com', 'ip4_address': '2.2.2.2'},
{'query_name': 'google.com', 'ip4_address': '3.3.3.3'}
]
query_name = "google.com"
ip_addresses = [d["ip4_address"] for d in data if d["query_name"] == query_name]
new_data = {
"query_name": query_name,
"ip4_address": ip_addresses,
"count": str(len(ip_addresses))
}
如果ip_addresses
应该是一个元组或列表,那么从所需的输出中并不会立即显而易见。我确定您知道如何将列表投射到元组。