Python:从列表解析(psutil)获取唯一值

时间:2018-10-11 11:30:57

标签: python psutil

我想从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中的功能之一?

1 个答案:

答案 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