![](/img/trans.png)
[英]Writing a Python Dictionary consisting of lists for values to CSV in long data format
[英]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
使其更容易測試其是否按照您的要求進行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.