我想从psutil
获得唯一的进程名称,PID和侦听端口。
我目前有以下代码:
names, pids, ports = zip(*[(
proc.info['name'],
proc.info['pid'],
port.laddr.port)
for proc in psutil.process_iter(attrs=['name', 'pid']) if 'java' in proc.info['name']
for port in proc.connections() if port.status == psutil.CONN_LISTEN
])
问题是进程名称和PID重复,以匹配嵌套for循环(端口)中的项目数:
>>> names
('java', 'java', 'java', 'java', 'java', 'java', 'java', 'java')
>>> pids
(15208, 15208, 15208, 15208, 15208, 15208, 15208, 15748)
>>> ports
(7574, 7574, 9462, 9463, 9461, 60588, 9463, 3875)
我想我以后可以将它们转换为sets
,但我希望有一种更好的,更Python化的方式来做到这一点而又不浪费资源。
更新时间:UTC 2018年10月11日星期四14:36:33
基于@Rouven B的回答。我现在有以下代码:
names = set()
pids = set()
ports = set()
for proc in psutil.process_iter(attrs=['name', 'pid']):
if 'java' not in proc.info['name']:
continue
names.add(proc.info['name'])
pids.add(proc.info['pid'])
for port in proc.connections():
if port.status == psutil.CONN_LISTEN:
ports.add(port.laddr.port)
但是我仍然想知道是否还有其他方法,也许使用itertools中的功能之一?
答案 0 :(得分:1)
这里是列表理解,可消除重复项
names, pids, ports = zip(*[
(proc.info['name'], proc.info['pid'], port.laddr.port)
for proc in psutil.process_iter(attrs=['name', 'pid']) if 'java' in proc.info['name']
if any([port.status == psutil.CONN_LISTEN for port in proc.connections()])
]*)
但这不容易阅读。怎么样
names = []
pids = []
ports = []
for proc in psutil.process_iter(attrs=['name', 'pid']):
if 'java' not in proc.info['name']:
continue
for port in proc.connections():
if port.status == psutil.CONN_LISTEN:
names.append(proc.info['name'])
pids.append(proc.info['pid'])
ports.append(port.laddr.port)
break
但是我想说,使用set
来消除重复项也是一个非常Python化的解决方案。它不应该太慢,也不会改变算法的时间复杂度(用O表示)。
编辑:我误解了您想要实现的目标。这是另一种紧凑的方法(仍然不太可读)
names, pids, ports = zip(*[(
proc.info['name'],
proc.info['pid'],
[conn.laddr.port for conn in proc.connections()
if conn.status == psutil.CONN_LISTEN])
for proc in psutil.process_iter(attrs=['name', 'pid'])
if 'java' in proc.info['name']
])
ports = list(sum(o, ())) # flatten list of lists of ports