简体   繁体   中英

Python lambda function to sort list according to dictionary

The sample codes bellow retrieve all the runing procces and print them. They've bee written following the 3rd example here and final one from here . Problem is I cannot figure out why only the first one retrieves process sorted as desired.

I think it is related to the lambda function construction. But the rightly running sample, the first one, seems to mix the local p variable of the for statement with the p.dict dictionary, making me get stuck.

First Sample:

import psutil

procs = []

for p in psutil.process_iter():
    try:
        p.dict = p.as_dict(['pid', 'name'])
    except psutil.NoSuchProcess:
        pass
    else:
        procs.append(p)

processes = sorted(procs, key=lambda p: p.dict['name'], reverse=False)

print(processes)

The second sample:

import psutil

procs = []

for proc in psutil.process_iter():
    try:
        procs_dic = proc.as_dict(['pid', 'name'])
    except psutil.NoSuchProcess:
         pass
    else:
        procs.append(proc)

processes = sorted(procs, key=lambda ordem: procs_dic['name'], reverse=False)

print(processes)

Your second code snippet's lambda looks up 'name' in the same dictionary no matter what object it's passed; how could that possibly work?

Your third doesn't even seem to be trying to sort the processes; I'm not sure what it has to do with the question.

The change you've made to turn the first snippet into the second is evidently motivated by your concern that the first

seems to mix the local p variable of the for statement with the p.dict dictionary

and I'd be happy to help but I'm afraid I don't understand what problem it is you see. Perhaps the following may help? There are two variables here called p . The first is used in the loop over processes; each time round the loop its value is a process object, and we give that process object a dict attribute containing an entry for 'name' . The second is the argument to your anonymous function (lambda): its value is also always a process object. You could give them different names if you wanted and it wouldn't break anything, but actually I think it's clearer as it is: in this little bit of code, p is what you call a variable whose value is a process object. But nothing's getting "mixed up".

In the first sample, the lambda function takes some var p and returns p.dict['name'] . You could change p here to x or whatever you want: it's just a placeholder.

In the second sample, key=lambda ordem: procs_dic['name'], reverse=False) , the lambda takes something called ordem and then only returns procs_dic['name'] over and over again.

The way the key works in sorted is this: as it is iterating over the elements and sorting them, it calls the lambda on every element to determine what value to sort it by.

My guess is that you want the sorted line of code in the 2nd example to look like this:

processes = sorted(procs, key=lambda x: x.name(), reverse=False)

Note that Process.name() returns the name of the process.

Try using a dictionary mapping Process es to dictionaries containing their information.

proc_dict = {}
for proc in psutil.process_iter():
    try:
        proc_dict[proc] = proc.as_dict(['name', 'pid'])
    except psutil.NoSuchProcess:
        continue

Then sort by the name value of the dictionary for that process.

print(*sorted(proc_dict, lambda x: proc_dict[x]['name']))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM