1

ネストされたループで生成する辞書にカスタムソートを適用したいと考えています。常に 5 つのレコードが存在することはわかっていますが、調べたデータに基づいて他のレコードが存在する可能性もあります。私は基本的にこれら 5 つのレコードを特定の順序で並べたいと考えていますが、これら 5 つ以降のすべてのレコードの順序は重要ではありません。

たとえば、私はこれが欲しい:

{"Entries": [], "Groups": [], "Admin": [], "Network": [], "XYZ": [], "Subnets": []}

これにソートされます:

{"Admin": [], "Groups": [], "Network": [], "Subnets": [], "Entries": [], "XYZ": []}

したがって、辞書の先頭に特定の順序で配置する必要があるのは、Admin、Groups、Network、Subnets、および Entries の 5 つです。その後、残りのエントリの順序は重要ではありません。これどうやってするの?

4

5 に答える 5

3

そのためにはcollections.OrderedDictが必要です...

したがって、それに基づいて、ソリューションは次のようになります。

def custom_order(dct, spec):
    """
    dct - the dictionary
    spec - a list of dedicated keys
    """
    res = collections.OrderedDict()
    dct = dict(dct)
    for key in spec:
        if key in dct:
            res[key] = dct.pop(key)
    res.update(dct.items())
    return res
于 2012-11-14T16:49:32.963 に答える
3

あなたは最初にする必要があります

  • 項目のリストを取得して (キー、値) ペアのリストを作成する
  • 生成されたリストのカスタムソート
  • ソート結果に基づいて OrderedDict を作成します

これは、キーの長さに基づいてデータをソートする例です

>>> from collections import OrderedDict
>>> some_dict = {"Entries": [], "Groups": [], "Admin": [], "Network": [], "XYZ": [], "Subnets": []}
>>> some_dict = OrderedDict(sorted(some_dict.items(),key = lambda e:len(e[0])))
>>> some_dict
OrderedDict([('XYZ', []), ('Admin', []), ('Groups', []), ('Subnets', []), ('Network', []), ('Entries', [])])
于 2012-11-14T16:56:48.773 に答える
1

データをペアのリストとして保存します。

于 2012-11-14T16:52:48.243 に答える
0

状況全体へのアプローチ方法を再考し、自分に合った方法を見つけました。

次のようなデータセットを使用します。

{"Entries": [], "Groups": [], "Admin": [], "Network": [], "XYZ": [], "Subnets": []}

私は次のことをするだけで、うまくいきます:

for menu in ["Admin", "Groups", "Network", "Subnets", "Entries"]:
    try:
        doWork(my_dataset[menu])
        del my_dataset[menu]
    except KeyError:
        # The user might not have any entries for that menu, so don't worry about it
        pass
for menu in my_dataset.keys():
    doWork(my_dataset[menu])

つまり、基本的には、5 つのアイテムに対して必要なことを行い、データセットから削除します。このコードブロックの後に上記のデータセットを使用していないため、これを行うことに満足しています。作業を行った後、残りのものは不要なので削除しません。ガベージ コレクションは、関数の完了後にデータセット全体を吹き飛ばすだけですよね?

于 2012-11-15T16:34:48.213 に答える
0

私はまったく同じ問題を抱えていて、軽量の一般的な解決策を考案しました:

from collections import OrderedDict

def make_custom_sort(orders):
    orders = [{k: -i for (i, k) in enumerate(reversed(order), 1)} for order in orders]
    def process(stuff):
        if isinstance(stuff, dict):
            l = [(k, process(v)) for (k, v) in stuff.items()]
            keys = set(stuff)
            for order in orders:
                if keys.issuperset(order):
                    return OrderedDict(sorted(l, key=lambda x: order.get(x[0], 0)))
            return OrderedDict(sorted(l))
        if isinstance(stuff, list):
            return [process(x) for x in stuff]
        return stuff
    return process

まず、カスタム オーダーの並べ替え関数のインスタンスを作成します。

custom_sort = make_custom_sort([ ["Admin", "Groups", "Network", "Subnets", "Entries"] ])

さて、実際の並べ替え:

result = custom_sort(my_dataset)

欠落しているキーは、不特定の順序で最後に拒否されます。このクロージャーは再帰的であることに注意してください。二重括弧で示されているように、構造内にネストされたさまざまな辞書が必要とする数の並べ替え順序を指定できます。

GitHub のプロジェクト: https://github.com/laowantong/customsort

于 2014-07-29T20:14:18.303 に答える