0

以下のキー、値形式の辞書があります。

PairDict= {(19, 6): 13, (2, 29): 10, (38, 8): 20, (38, 5): 5} 

キーは 2 つの要素を持つタプルで、値はサイクル数を表します。

タプルの最初の要素の特定の並べ替え順序に基づいて、辞書をリストに並べ替える必要があります。

SortOrder= [(38, 25), (19, 13), (2, 10)]

ここで、上記の SortOrder のタプルの最初の要素は、PairDict のタプル キーの最初の要素を表します。SortOrder のタプルの 2 番目の要素は、PairDict の最初の要素のサイクル数の合計を表します

PairDict に同じ最初の要素を持つ複数のタプルがある場合、そのソート順はとにかく、たとえば 38 を最初にソートする必要があります。PictDict には、38 で始まる 2 つのタプル、つまり と が(38, 8)あり(38, 5)ます。その順序は または のいずれ[(38, 8): 20, (38, 5): 5][(38, 5): 5, (38, 8): 20]です。

SortOrder に基づく順序付け PairDict の期待される出力は、次のようになります。

SortedPairDict= [((38, 8), 20), ((38, 5), 5), ((19, 6), 13), ((2, 29), 10)], 

また

SortedPairDict= [((38, 5), 5), ((38, 8), 20), ((19, 6), 13), ((2, 29), 10)],

検索しようとしましたが、私が得ることができる最も近い例は、

参照: Python で辞書のリストを任意に並べ替える

しかし、私のキーがタプルであるため、その例で私のコードを実現するのに問題があります。

これについて読むことができる例があるかどうかを教えてください。または、これを処理するための最良の方法を教えてください。

あなたの助けに感謝。メリークリスマス :-)

ありがとう。

更新 : timeit 分析 Amber と Ashwini のソリューション

PairDict= {(19, 8): 13, (2, 29): 10, (38, 8): 20, (2, 18): 10, (43, 8): 20, (5, 13): 15, (6, 21): 9, (7, 25): 11, (8, 19): 15, (44, 4): 20, (0, 10): 9, (0, 36): 9, (21, 6): 19, (30, 4): 17, (24, 0): 11, (3, 14): 21, (6, 12): 9, (7, 20): 11, (20, 7): 10, (5, 23): 15, (11, 5): 15, (37, 6): 13, (34, 8): 20, (18, 2): 10, (0, 24): 9, (12, 6): 13, (8, 38): 15, (39, 5): 18, (42, 5): 17, (26, 7): 22, (10, 0): 9, (31, 0): 14, (3, 27): 21, (6, 37): 9, (36, 0): 17, (0, 33): 9, (41, 0): 18, (5, 39): 15, (5, 42): 15, (6, 40): 9, (5, 11): 15, (9, 3): 21, (25, 7): 13, (7, 28): 11, (3, 9): 21, (29, 2): 4, (32, 4): 22, (0, 41): 9, (40, 6): 10, (28, 7): 20, (6, 15): 9, (17, 4): 23, (23, 5): 18, (16, 5): 23, (8, 34): 15, (5, 16): 15, (8, 22): 15, (8, 43): 15, (4, 17): 19, (13, 5): 23, (4, 30): 19, (7, 26): 11, (15, 6): 13, (4, 44): 19, (22, 8): 18, (0, 31): 9, (35, 5): 23, (14, 3): 20, (33, 0): 12, (5, 35): 15, (27, 3): 16, (4, 32): 19}

SortOrder= [(5, 105), (4, 76), (8, 75), (3, 63), (0, 54), (6, 45), (7, 44), (13, 23), (16, 23), (17, 23), (35, 23), (26, 22), (32, 22), (9, 21), (2, 20), (14, 20), (28, 20), (34, 20), (38, 20), (43, 20), (44, 20), (21, 19), (22, 18), (23, 18), (39, 18), (41, 18), (30, 17), (36, 17), (42, 17), (27, 16), (11, 15), (31, 14), (12, 13), (15, 13), (19, 13), (25, 13), (37, 13), (33, 12), (24, 11), (18, 10), (20, 10), (40, 10), (10, 9), (29, 4)]

[5]: %timeit amber() 10000 ループ、Best of 3: ループあたり 71.1 us

[6]: %timeit ashwc() 1000 ループ、ベストオブ 3: ループあたり 753 us

4

2 に答える 2

5
sortkeys = dict((x[0], index) for index,x in enumerate(SortOrder))
SortedPairDict = sorted(PairDict.iteritems(),
                        key=lambda x: sortkeys[x[0][0]])

ここでの考え方は、並べ替えを再発明したくないということです。そのため、Python の組み込みsorted()関数を使用できる形式にしたいと考えています。

そのためには、sorted()受け入れられる形式の注文情報が必要です。これを行う最も簡単な方法は、順序付けられた整数のセットなど、Python が既にソート方法を知っている「キー」を定義することです。

この場合、SortOrder リストの値をそのリスト内の位置にマッピングすることでこれを行います。次に、キー関数を定義して、タプル キーの最初の要素に対応する SortOrder 位置を単純に検索します。


>>> sortkeys = dict((x[0], index) for index,x in enumerate(SortOrder))
>>> SortedPairDict = sorted(PairDict.iteritems(),
...                         key=lambda x: sortkeys[x[0][0]])
>>> SortedPairDict
[((38, 5), 5), ((38, 8), 20), ((19, 6), 13), ((2, 29), 10)]
于 2012-12-24T20:33:17.363 に答える
1

itertools.groupbyこれらの場合に非常に役立つと思うので、代替案について言及するだけでよいと思いました。(実際、私itertoolsは多くの場合に非常に便利だと思いますが、私は多くの関数型プログラミングの歴史を持っています。) ここでの利点は、別の辞書を作成する必要がないことです。これにより、パフォーマンスが向上する場合とされない場合があります。

    from itertools import groupby

    PairDict= {(19, 6): 13, (2, 29): 10, (38, 8): 20, (38, 5): 5}
    key = lambda i: i[0][0]
    SortedPairDict = groupby(sorted(PairDict.iteritems(), key=key), key=key)

SortOrder、次を使用して計算できるはずです。

    SortOrder = [ (k, sum(v[1] for v in g)) for k, g in SortedPairDict ]

上記の長い例のリストは特定の順序ではないことに注意してください。そのため、何か誤解しているかどうかはわかりません。

于 2012-12-25T08:09:50.463 に答える