Python 如何获得列表中每个项目的计数?
背景: 我有一个程序,可以解析我的盒子上连接尝试的日志文件。 它拉取一个ip地址列表,然后我有其他功能,我想在这个信息列表上运行,特别是一个功能没有按预期工作。它应该得到每个国家的连接尝试次数 代码-ip_tools.pyPython 如何获得列表中每个项目的计数?,python,python-2.7,Python,Python 2.7,背景: 我有一个程序,可以解析我的盒子上连接尝试的日志文件。 它拉取一个ip地址列表,然后我有其他功能,我想在这个信息列表上运行,特别是一个功能没有按预期工作。它应该得到每个国家的连接尝试次数 代码-ip_tools.py #!/usr/bin/python import requests import json import socket #function to get the ip address of the host user def get_host_ipad(): ho
#!/usr/bin/python
import requests
import json
import socket
#function to get the ip address of the host user
def get_host_ipad():
host_ip_request = requests.get("http://ipinfo.io/ip")
return host_ip_request.text
#function to get gelocation info of a remote host
def get_rhost_geo(ipad):
full_geo_info = {}
rhost_ip_request = requests.get("http://ipinfo.io/%s/json" % (ipad))
json_response = json.loads(rhost_ip_request.text)
for value in json_response:
full_geo_info.update({str(value) : str(json_response[value])})
return full_geo_info
#function to return country of rhost
def get_geo_country(ipad):
geo_info = get_rhost_geo(ipad)
geo_country = geo_info["country"]
return geo_country
#function to perform reverse dns lookup
def get_rhost_url(ipad):
try:
rhost_url = socket.gethostbyaddr(ipad)
rhost_url = rhost_url[0]
except Exception:
rhost_url = 'No URL found for this ip address.'
return rhost_url
#main function to run the code only if called directly
def Main():
#printing the options menu and taking a variable to be passed
print '_' * 20
print "1: Get your ip address: \n"
print "2: Get Geolocation of an IP address: \n"
print "3: Atempt getting URL from IP address"
sel = raw_input("Choose an option: \n")
#if statement to control menu navigation
if sel == '1':
print get_host_ipad()
#calls the get_rhost_ipad function defined above on user input
elif sel == '2':
ipad = raw_input("Which IP address?: \n")
print get_rhost_geo(ipad)
elif sel == 'quit':
quit()
elif sel == '3':
ipad = raw_input("Which IP address?: \n")
print get_rhost_url(ipad)
else:
print "Please choose one of the other options. \n"
if __name__=="__main__":
Main()
代码-log_auditor.py:
import re
import ip_tools
#global variable to open kippo log in read mode
MY_LOG = open("/path/to/log", "r").read()
#function to get ip address from log file with a regular expression
def get_ips_from_log():
re_ip_search = re.findall(r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b", MY_LOG)
return re_ip_search
#function to get attempts per unique ip address
def get_ip_count():
ip_log = get_ips_from_log()
ip_count = [(i, ip_log.count(i)) for i in set(ip_log)]
return ip_count
#function to get attempts per country
def get_country_count():
ip_list = get_ips_from_log()
get_country_count = [(ip_tools.get_geo_country(ip), ip_list.count(ip)) for ip in set(ip_list)]
return get_country_count
#main function to only run program when called:
def Main():
print get_country_count()
if __name__=='__main__':
Main()
所讨论的功能是:
#function to get attempts per country
def get_country_count():
ip_list = get_ips_from_log()
get_country_count = [(ip_tools.get_geo_country(ip), ip_list.count(ip)) for ip in set(ip_list)]
return get_country_count
不幸的是,它的输出如下所示:
[('CN', 2), ('CN', 566), ('NL', 2), ('CN', 3040), ('CN', 2), ('CN', 1042), ('CN', 2), ('US', 2), ('KR', 382), ('DE', 2), ('US', 127)]
如何进一步将其分组?使用字典跟踪每个国家/地区代码的总计数
from collections import defaultdict
def get_country_count():
ip_list = get_ips_from_log()
country_count = defaultdict(int)
for ip in set(ip_list):
country_count[ip_tools.get_geo_country(ip)] += ip_list.count(ip)
return country_count
如果我们不接触所有其他代码,函数可以像这样重写:
from collections import defaultdict
....
def get_country_count():
country_count = defaultdict(int)
for ip in get_ips_from_log():
country_count[ip_tools.get_geo_country(ip)] += 1
return country_count
或者如果使用获取地理位置国家/地区的成本很高
:
def get_country_count():
country_count = defaultdict(int)
ip_list = get_ips_from_log()
for ip in set(ip_list):
country_count[ip_tools.get_geo_country(ip)] += ip_list.count(ip)
return country_count
defaultdict
仅用于某个原因不要编写这样难看的结构:
def get_country_count():
....
for ....
country = ip_tools.get_geo_country(ip)
if country in country_count:
country_count[country] += ...
else:
country_count[country] = ...
你能发布你的预期输出吗?你的问题可以用一个示例输入列表、一个函数(你指出的那个)和一个预期输出的示例来解释。请缩小你的问题范围——人们对你的生活并不感兴趣;)你所说的“进一步分组”是什么意思?@Zenadix OP可能希望将
'CN'
的计数加在一起,因此,除了许多结果('CN',2),…,('CN',2)
之外,每个标签只需要一个:('CN',4)
。一旦你删除了所有无关的内容,我想大家都在寻找类似于集合.计数器(ip\u工具.获取ip\u列表中ip的地理位置(ip)
,在这种情况下,这是许多“如何计算事物”问题的重复。很好,我不知道这个库。现在的输出如下:defaultdict(,{'NL':2,'CN':4654,'DE':2,'US':141,'KR':448,'ID':14})
如何删除defaultdict(,?最终,只要信息在字典或元组列表中,它就可以满足我的需要。使用dict构造函数dict(count)
哪个将打印{'NL':2,'CN':4654,'DE':2,'US':141,'KR':448,'ID':14}
非常简单,我应该想到这一点。谢谢你的帮助,我对这一切还很陌生。要模拟一个带有集合的一行程序,似乎需要做很多工作。计数器
可以做什么,除了在二次时间而不是线性时间。为什么?谢谢你的回答。还有人提到使用defaultdict,我甚至不知道第二个代码段就是我将要使用的代码段。