簡體   English   中英

通過從另一個列表執行查找來替換元組列表中元素的有效方法(python)

[英]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 2nn*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.

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