簡體   English   中英

Python字典中的反向鍵(由列表組成)和值

[英]reverse keys (consisting of lists) and values in Python dictionary

我一直試圖從這里的其他帖子中弄清楚這一點,但是沒有。

我有一個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中,第一個鍵是列表(1, 'a') : [2] ,現在,這個鍵應變為(2, 'a'), [1] ...或(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的了解很少,所以如果我犯了一個太愚蠢的錯誤,請原諒我。)

這足夠復雜,我不會理會列表理解。 另外,我假設您不是要按任何嚴格順序查找值列表。

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)

這可以處理您的數據, 只是為了好玩而把它當作一個丑陋的hack

最好在更多的代碼行中這樣做,這樣更容易理解,但有時我無法抗拒編寫這種工具的誘惑。

希望能幫助到你。

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使其更容易測試其是否按照您的要求進行。

我認為有你的目的的理解有問題dict dict數據結構不應被視為以任何特定方式排序,因為它使用哈希表來訪問元素。 你應該閱讀文檔 ,並在實現細節的說明.items() 在這里也很重要。 事實證明,該實現可以給您看似期望的順序,但是您不應指望它。

如果順序對您很重要,那么您應該至少在順序中重要的代碼部分中使用list dict上使用.items()方法來獲取(key,value)對的列表,然后可以使用列表上的常規排序方法對它們進行任意排序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM