2

ここの他の投稿からこれを理解しようとしてきましたが、できませんでした。

私はPython辞書を持っています

old_dict = { (1,'a') : [2],
          (2,'b') : [3,4],
          (3,'x') : [5],
          (4,'y') : [5],
          (5,'b') : [3,4], 
          (5,'c') : [6],
          }

結果として次のようになるように、これを逆にする必要があります。

new_dict = { (6,'c') : [5],
          (5,'x') : [3],
          (5,'y') : [4],
          (4,'b') : [5, 2],
          (3,'b') : [5, 2], 
          (2,'a') : [1],
          }

(これは有限ステート マシンのエッジを表しており、逆方向に実行する必要があります。以前のように逆の入力を受け入れる必要があります)

たとえば、old_dict では、最初のキーは list でしたが(1, 'a') : [2]、これは(2, 'a'), [1]... になるか、またはetc に(4,'y') : [5]なる必要があります。(5,'y') : [4]

リスト内包表記でこれを解決しようとしていますが、まだ成功していません。

更新: FCの提案を試しましたが、どういうわけかコードを動作させることができません。次のように関数に挿入しました。

old_dict1 = { (1,'a') : [2],
          (2,'b') : [3,4],
          (3,'x') : [5],
          (4,'y') : [5],
          (5,'b') : [3,4], 
          (5,'c') : [6],
          }

def reverse_dict(old_dict):
    new_dict = {}
    add_to_dict = new_dict.setdefault

    map(lambda kv: add_to_dict(kv[0], []).append(kv[1]),   
        sum([[((x, k[1]), k[0]) for x in v] for k, v in old_dict.items()],
            []))        # sum will take this to start adding
    return new_dict

new_dict1 = reverse_dict(old_dict1)

print(new_dict1)

しかし、空の辞書しか返されません{}

私は何か間違っていますか?(私はPythonの知識がほとんどないので、ばかげた間違いをした場合はご容赦ください...)

4

3 に答える 3

8

これは十分に複雑なので、リスト内包表記を気にする必要はありません。また、厳密な順序の値リストを探しているわけではないと思います。

new_dict = {}
for k, vals in old_dict.items():
    k_num, k_char = k
    for num in vals:
        new_dict.setdefault((num, k_char), []).append(k_num)

またはdefaultdict:を使用して

new_dict = collections.defaultdict(list)
for k, vals in old_dict.items():
    k_num, k_char = k
    for num in vals:
        new_dict[(num, k_char)].append(k_num)

できるだけ簡潔にすることに興味がある人にとっては、このより圧縮されたバージョンもオプションであると私は思います。読みやすさの観点からこれについてどう思うかわからないので、もう少し明確にするために変数名を変更しました。

new_dict = collections.defaultdict(list)
for (num_in, char_in), nums_out in old_dict.items():
    for num_out in nums_out:
        new_dict[(num_out, char_in)].append(num_in)
于 2012-06-01T22:11:07.577 に答える
0

これはあなたのデータで機能します。楽しみのためだけに醜いハックと考えてください。

より多くのコード行でそれを行う方が理解しやすくなりますが、この仕掛けを書きたいという誘惑に抵抗できないことがあります。

それが役に立てば幸い。

def reverse_dict(old_dict):
    """
    >>> sorted(reverse_dict({(1,'a'): [2],
    ...               (2,'b'): [3,4],
    ...               (3,'x'): [5],
    ...               (4,'y'): [5],
    ...               (5,'b'): [3,4], 
    ...               (5,'c'): [6],
    ...              }).items())
    [((2, 'a'), [1]), ((3, 'b'), [2, 5]), ((4, 'b'), [2, 5]), ((5, 'x'), [3]), ((5, 'y'), [4]), ((6, 'c'), [5])]
    """
    new_dict = {}
    add_to_dict = new_dict.setdefault       # you could use a [defaultdict][1] instead

    map(lambda kv: add_to_dict(kv[0], []).append(kv[1]),   # if kv[0] not in dict get [] and add to it
        sum([[((x, k[1]), k[0]) for x in v] for k, v in old_dict.items()],
            []))        # sum will take this to start adding
    return new_dict

コードをテストするには、コードをファイルにコピーして、次のso.pyように実行します。

$ python -m doctest so.py -v
Trying:
    sorted(reverse_dict({(1,'a'): [2],
                  (2,'b'): [3,4],
                  (3,'x'): [5],
                  (4,'y'): [5],
                  (5,'b'): [3,4], 
                  (5,'c'): [6],
                 }).items())
Expecting:
    [((2, 'a'), [1]), ((3, 'b'), [2, 5]), ((4, 'b'), [2, 5]), ((5, 'x'), [3]), ((5, 'y'), [4]), ((6, 'c'), [5])]
ok
1 items had no tests:
    so
1 items passed all tests:
   1 tests in so.reverse_dict
1 tests in 2 items.
1 passed and 0 failed.
Test passed.

それがdoctestあなたが望むことをしているかどうかをテストしやすくするために使用します。

于 2012-06-01T22:51:38.140 に答える
-1

の目的の理解に問題があると思いますdict。データ構造はdict、要素へのアクセスにハッシュ テーブルを使用するため、特定の方法で順序付けされていると考えるべきではありません。ドキュメントを読む必要があり、.items() ここにある実装の詳細に関するメモも重要です。実装により、期待しているように見える順序が得られる場合がありますが、それを当てにするべきではありません。

順序が重要な場合はlist、コードの少なくとも順序が重要な部分で a を使用する必要があります。.items()のメソッドを使用してペアdictのリストを取得すると、リスト(key,value)の通常の並べ替え方法を使用して、好きな方法で並べ替えることができます。

于 2012-06-02T05:27:15.757 に答える