是否有可能產生一個比 O(n2) 具有更好時間復雜度的襯里(即理解),如下所示?
my_map = {'A': 'x',
'B': 'y',
'C': 'x',
'D': 'z'}
rev_map = {b: [a2 for a2 in my_map.keys() if my_map[a2] == b]
for a, b in my_map.items()}
沒有找到任何相關的 Reverse/invert 字典映射。
uj5u.com熱心網友回復:
問題不在于單行。問題是理解是針對運算式映射/過濾操作的。并且您無法使用帶有dict's. 你需要一個reduce. 當然,要保持在一條線上,加上一個lambda表情,會很hacky和丑陋:
單線:
reduce(lambda d, k: [d.setdefault(my_map[k], []).append(k), d][1], my_map, {})
在 REPL 中:
>>> my_map = {'A': 'x',
... 'B': 'y',
... 'C': 'x',
... 'D': 'z'}
>>> import functools
>>> functools.reduce(lambda d, k: [d.setdefault(my_map[k], []).append(k), d][1], my_map, {})
{'x': ['A', 'C'], 'y': ['B'], 'z': ['D']}
但請不要使用這個。只需撰寫常規的 for 回圈即可。
uj5u.com熱心網友回復:
這是一個O(n log n)單行:
>>> {k : list(map(itemgetter(1), g)) for k, g in groupby(sorted(map(itemgetter(1, 0), my_map.items())), itemgetter(0))}
{'x': ['A', 'C'], 'y': ['B'], 'z': ['D']}
所需的進口是:
from itertools import groupby from operator import item getter
uj5u.com熱心網友回復:
我在這里跑題了,因為我不明白為什么這必須作為一個單行來完成。考慮一下:
from timeit import timeit
my_map = {'A': 'x',
'B': 'y',
'C': 'x',
'D': 'z'}
def func1():
return {b: [a2 for a2, b2 in my_map.items() if b2 == b] for b in my_map.values()}
def func2():
nm = {}
for k, v in my_map.items():
nm.setdefault(v, []).append(k)
return nm
for func in func1, func2:
print(func.__name__, timeit(lambda: func()))
輸出:
func1 1.9566871839997475
func2 0.6075634010003341
請注意,字典理解所需的時間是更傳統/簡單方法的 3 倍以上。
編輯:
當源字典較大時,兩種方法之間的時間差(因子)顯著增加。
from timeit import timeit
import random
import string
my_map = {}
for k in string.ascii_uppercase:
my_map[k] = random.choice('xyz')
print(my_map)
def func1():
return {b: [a2 for a2, b2 in my_map.items() if b2 == b] for b in my_map.values()}
def func2():
nm = {}
for k, v in my_map.items():
nm.setdefault(v, []).append(k)
return nm
for func in func1, func2:
print(func.__name__, timeit(lambda: func(), number=250_000))
輸出:
{'A': 'y', 'B': 'x', 'C': 'x', 'D': 'y', 'E': 'y', 'F': 'y', 'G': 'z', 'H': 'x', 'I': 'y', 'J': 'z', 'K': 'z', 'L': 'y', 'M': 'x', 'N': 'x', 'O': 'z', 'P': 'x', 'Q': 'x', 'R': 'x', 'S': 'y', 'T': 'y', 'U': 'x', 'V': 'x', 'W': 'x', 'X': 'z', 'Y': 'z', 'Z': 'y'}
func1 8.602543555000011
func2 0.7367826070003503
證明單行并不總是一個好主意
uj5u.com熱心網友回復:
如果我猜對了,你會想像這樣反轉你的字典:
my_map = {
'A': 'x',
'B': 'y',
'C': 'x',
'D': 'z'
}
rev_map = {
'x': ['A', 'C'],
'y': ['B'],
'z': ['Z'],
}
它可以一次性完成并使用以下代碼為您提供 O(n)
from collections import defaultdict
rev_map = defaultdict(list)
for key, value in my_map.items():
rev_map[value].append(key)
然后,如果您想將串列中具有單個值的鍵轉換為字串,那么您可以再執行一遍并執行此操作,這仍然是 O(n)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/492680.html
下一篇:一起列印不同字典中值的乘積
