Python: получить уникальные значения из списка понимания (psutil) - PullRequest
0 голосов
/ 11 октября 2018

Я хотел бы получить уникальные имена процессов, PID и прослушивающие порты от psutil.

В настоящее время у меня есть следующий код:

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 (ports):

>>> 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, но я надеюсь, что есть лучший, более питонический способсделать это, не тратя ресурсов.

Обновление: чт 11 окт 14:36:33 UTC 2018

На основании ответа @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 голосов
/ 11 октября 2018

Вот список для избавления от дубликатов

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 для избавления от дубликатов также является довольно питонным решением, я бы сказал.Он не должен быть слишком медленным и не меняет временную сложность (в терминах O) алгоритма.

EDIT : я неправильно понял, чего вы хотели достичь.Здесь идет еще один компактный подход (все еще не очень читаемый)

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
...