简体   繁体   English

如何排序python命令的输出?

[英]How do you sort the output of a python command?

Python beginner here. Python初学者在这里。 Let's say that I have something at the end of my script that queries info from a system and dumps it into this format: 假设我在脚本的末尾有一些内容,可以从系统中查询信息并将其转储为以下格式:

print my_list_of_food(blah)

and it outputs a list like: 它输出一个类似的列表:

('Apples', 4, 4792320)
('Oranges', 2, 2777088)
('Pickles', 3, 4485120)
('Pumpkins', 1, 5074944)
('more stuff', 4545, 345345)

How do I then sort that output based on the 2nd field so that it would look like this: 然后,如何根据第二个字段对该输出进行排序,使其看起来像这样:

('Pumpkins', 1, 5074944)
('Oranges', 2, 2777088)
('Pickles', 3, 4485120)
('Apples', 4, 4792320)

Other than importing a bash command to cut -d "," -f 2 | head 4 除了导入bash命令以cut -d "," -f 2 | head 4 cut -d "," -f 2 | head 4 I'd rather use python. cut -d "," -f 2 | head 4我宁愿使用python。 I know I can use sorted or sort to sort an existing tuple or dictionary but I'm not sure of how to sort the output of a print. 我知道我可以使用sorted或sort对现有的元组或字典进行排序,但是我不确定如何对打印输出进行排序。 I've done some research and everything points to implementing sort into my script instead of sorting a print output but who knows, maybe someone has a solution. 我已经进行了一些研究,所有内容都指向在脚本中实现排序,而不是对打印输出进行排序,但是谁知道,也许有人可以解决。 Thanks. 谢谢。

UPDATE: 更新:

Thanks everyone. 感谢大家。 I've tried to make all of the solutions work but I keep getting this error: 我试图使所有解决方案都能正常工作,但我不断收到此错误消息:

File "test.py", line 18, in <lambda>
    print sorted(my_list_of_food(blah), key=lambda x: x[1])
TypeError: 'int' object is unsubscriptable

File "test.py", line 18, in <lambda>
    print(sorted(my_list_of_food(blah), key=lambda k: k[1]))
TypeError: 'int' object is unsubscriptable

I tried to include this at the beginning of the script: 我试图在脚本的开头包含以下内容:

from __future__ import print_function 

but no luck. 但没有运气。

You can use the key argument to the sort. 您可以使用key参数进行排序。 In your case, 就你而言

print(sorted(list_of_food, key=lambda k:k[1]))

will do the trick. 会成功的 The key function should return an integer, usually. 通常,键函数应返回一个整数。

If it prints out that way, than either my_list_of_food(blah) returns a string, or it returns a class instance that has a __repr__ method that returns that string... Your best bet is to get data in the actual list format before it becomes a string. 如果以这种方式打印出来,则my_list_of_food(blah)返回一个字符串,或者返回一个具有__repr__方法的类实例,该类实例返回该字符串...最好的选择是在数据变为列表之前获取实际的列表格式一个字符串。

If it returns a class instance, get the list and sort on it using key... Otherwise you need to parse the text, so I'll address that part only: 如果它返回一个类实例,请获取列表并使用键对其进行排序...否则,您需要解析文本,因此,我仅讨论该部分:

# this is assuming the structure is consistent
# function to parse a line of the form "('{text}', {int}, {int})" into tuple members using regex
import re
re_line = re.compile(r"\('(?P<name>\w*)',\s?(?P<int1>\d+)\s?,\s?(?P<int2>\d+)\)")
def ParseLine(line):
    m = re_line.match(line)
    if m:
        return (m.group('name'), int(m.group('int1')), int(m.group('int2')))
    # otherwise return a tuple of None objects
    else:
        return (None, None, None)

# final sorted output (as tuples of (str, int, int) )
sorted( 
    [ParseLine(line) for line in my_list_of_food(blah).splitlines()],
    key = lambda tup: tup[1]
)

You can't sort after outputting to stdout . 输出到stdout后无法排序。 Well, you shouldn't, since it's heavily complicating a simple task. 好吧,您不应该这样做,因为它使一个简单的任务变得非常复杂。 Instead, you sort the value and print the result: 相反,您对值进行排序并打印结果:

print sorted(my_list_of_food(blah), key=lambda x: x[1])

The part where you were having difficulties is sorting by the second field; 您遇到困难的部分是按第二个字段排序; that's why that key argument is there - to override the default ordering (which would be the first item of the tuple). 这就是其中存在key参数的原因-覆盖默认顺序(这将是元组的第一项)。 To learn more about key functions, check this section on the python Sorting HOW TO 要了解有关关键功能的更多信息,请在python Sorting HOW TO上查看此部分

If you're still wondering, technically, you could sort the stdout output if you replaced sys.stdout with a wrapper object that buffered the output then sorted and printed it (to the real stdout) periodically, but it's pointless and hard to get right, IMHO. 如果你仍然不知道,从技术上讲,你可以排序的stdout ,如果你换成输出sys.stdout与缓冲的输出然后整理并打印它(到真正的标准输出)定期的包装物,但它是没有意义的,很难得到正确, 恕我直言。

OK: If you really have to do it that way: capture the output of the function in a StringIO object and sort the lines read back from that object. OK:如果确实需要这样做,请执行以下操作:在StringIO对象中捕获函数的输出,并对从该对象读取的行进行排序。

import sys
try:
    from StringIO import StringIO
except:
    from io import StringIO

a = [ ('Apples', 4, 4792320), 
    ('Oranges', 2, 2777088), 
    ('Pickles', 3, 4485120), 
    ('Pumpkins', 1, 5074944), 
    ('more stuff', 4545, 345345) ]

[Step 1] [第1步]

out = StringIO()    # create a StringIO object
sys.stdout = out    # and redirect stdout to it
for item in a : print (item)        # print output
sys.stdout = sys.__stdout__     # redirect stdout back to normal stdout

out.seek(0)     # rewind StringIO object
s = out.readlines() # and read the lines.

[Step 2: define a key function to split the strings at comma, [第2步:定义一个键函数,以逗号分隔字符串,

and compare the 2nd field numerically. 并在数值上比较第二个字段。 ] ]

def sortkey(a):
   return int(a.split(',')[1].strip())

[Step 3: sort and print] [步骤3:排序和打印]

s.sort(key=sortkey)
for line in s: print (line)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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