3

パイソン初心者です。スクリプトの最後に、システムから情報を照会して次の形式にダンプする何かがあるとします。

print my_list_of_food(blah)

次のようなリストを出力します。

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

次に、2 番目のフィールドに基づいてその出力を並べ替えて、次のようにするにはどうすればよいですか。

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

bash コマンドをインポートする以外は、cut -d "," -f 2 | head 4むしろ python を使用したいと思います。sorted または sort を使用して既存のタプルまたは辞書をソートできることは知っていますが、出力の出力をソートする方法がわかりません。私はいくつかの調査を行いましたが、印刷出力を並べ替えるのではなく、スクリプトに並べ替えを実装することをすべて示していますが、誰かが解決策を持っている可能性があります。ありがとう。

アップデート:

みんな、ありがとう。すべてのソリューションを機能させようとしましたが、次のエラーが発生し続けます。

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

スクリプトの冒頭にこれを含めようとしました:

from __future__ import print_function 

しかし運がない。

4

4 に答える 4

7

ソートには key 引数を使用できます。あなたの場合、

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

トリックを行います。通常、キー関数は整数を返す必要があります。

于 2013-01-30T20:36:43.110 に答える
1

に出力した後はソートできませんstdout。単純なタスクが非常に複雑になるため、そうすべきではありません。代わりに、値をソートして結果を出力します。

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

問題があったのは、2 番目のフィールドでの並べ替えです。それがその引数が存在する理由ですkey-デフォルトの順序付けをオーバーライドします(タプルの最初のアイテムになります)。主要な機能の詳細については、python Sorting HOW TO のこのセクションを確認してください。

それでも疑問に思っている場合は、技術的には、出力をバッファリングし、それを定期的に並べ替えて (実際の標準出力に) 印刷するラッパー オブジェクトに置き換えれば、出力を並べ替えることができますが、それは無意味であり、私見です。stdoutsys.stdout

于 2013-01-30T20:32:07.673 に答える
1

そのように印刷された場合my_list_of_food(blah)、文字列を返すか、その文字列を返すメソッドを持つクラスインスタンスを__repr__返します...最善の策は、文字列になる前に実際のリスト形式でデータを取得することです。

クラス インスタンスが返された場合は、リストを取得し、キーを使用して並べ替えます。それ以外の場合は、テキストを解析する必要があるため、その部分のみを扱います。

# 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]
)
于 2013-01-30T20:32:44.417 に答える
0

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) ]

[ステップ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.

[ステップ 2: 文字列をカンマで分割するキー関数を定義し、

2番目のフィールドを数値的に比較します。]

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

【ステップ3:仕分けて印刷】

s.sort(key=sortkey)
for line in s: print (line)
于 2013-01-30T21:43:08.063 に答える