[英]Efficient way to replace an element in a list of tuples by performing look up from another list (python)
我有一個元組列表,像這樣:
tuple_list = [(id-1,value-1),(id-2,value-2),....(id-n,value-n)]
同樣,我有一個與上面列表中的ids
相關的對象列表,即:
object_list = [<obj-3>,<obj-1>,....<obj-n>]
請注意, object_list
中的順序不同。
我想生成一個與上面的第一個完全一樣的新列表,除了id
,它應該包含對象本身。
resulting_list = [(<obj-1>,value-1),(<obj-2>,value-2),...(<obj-n>,value-n)]
什么是執行此操作的最有效方法?
我正在兩個循環內嘗試它:
resulting_list = []
for tpl in tuple_list:
for obj in object_list:
if tpl[0] == obj.id
resulting_list.append((obj,tpl[1]))
構造一個dict
,其中鍵是對象id,值是對象。 然后遍歷列表理解中的tuple_list
,並從dict
和原始列表中的值為每個元組輸出對象:
class Obj:
def __init__(self, id):
self.id = id
def __repr__(self):
return 'Obj({})'.format(self.id)
tuple_list = [(0, 'Zero'), (1, 'One'), (2, 'Two'), (3, 'Three'), (4, 'Four')]
object_list = [Obj(i) for i in range(4, -1, -1)]
d = {o.id: o for o in object_list}
result = [(d[_id], val) for _id, val in tuple_list]
print(result)
輸出:
[(Obj(0), 'Zero'), (Obj(1), 'One'), (Obj(2), 'Two'), (Obj(3), 'Three'), (Obj(4), 'Four')]
上面的時間復雜度是O(n) ,其中帶有嵌套循環的原始代碼是O(n ^ 2) 。
如果您的列表有長度n
那么當前的算法確實n
於外循環迭代,並n
每個內循環迭代,產生總共n*n
。 找到匹配項后,您可以通過打破內循環來改進它。 得出的平均值為n*n/2
。
但是最好做兩個長度為n
循環,因為對於大的n
2n
比n*n
小得多。 在下面的代碼中,第一個循環構造一個字典,其中對象id為鍵,而對象本身為值。 然后,第二個循環可以從其ID快速找到對象。
obj_map = {obj.id: obj for obj in object_list}
resulting_list = [(obj_map[k], v) for k, v in tuple_list]
如果有可能,在一些IDS tuple_list
沒有一個匹配的對象obj_map
,你不想失敗,一個KeyError
在那種情況下,你可以做
resulting_list = [(obj_map.get(k), v) for k, v in tuple_list]
它將為任何缺少的對象提供“ None
”。
或者,
resulting_list = [(obj_map.get(k, default_object), v) for k, v in tuple_list]
這將為缺少的對象提供default_object
。
...
i = object_list.index(tpl[0]) if tpl[0] in tuple_list else -1
if i > -1:
resulting_list.append((object_list[i],tpl[1]))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.