簡體   English   中英

Python:順序重要的嵌套列表的交集

[英]Python: intersection of nested lists where order matters

我想在維護順序的同時找到嵌套列表之間的交集。

taxa = [['E_pyrifoliae_Ep1_96', 'Bacteria', 'Proteobacteria', 'Gammaproteobacteria', 'Enterobacteriales', 'Enterobacteriaceae', 'Erwinia'],
 ['E_amylovora_CFBP1430', 'Bacteria', 'Proteobacteria', 'Gammaproteobacteria', 'Enterobacteriales', 'Enterobacteriaceae', 'Erwinia'], 
 ['E_amylovora_ATCC49946', 'Bacteria', 'Proteobacteria', 'Gammaproteobacteria', 'Enterobacteriales', 'Enterobacteriaceae', 'Erwinia']]

找到我的交集點:

set.intersection(*map(set, taxa))

要么

set(taxa[0]).intersection(*taxa)

但原始訂單沒有保留。

set(['Erwinia', 'Gammaproteobacteria', 'Enterobacteriaceae', 'Enterobacteriales', 'Proteobacteria', 'Bacteria'])

基本上,我需要做的是找到嵌套列表之間的最后一個共同元素(它們是分類學分類)。 因此,當我可以調用最后一個條目時,我不需要找到所有交叉點,只需要找到最后一個或所有交叉點。

intersection_lst[-1]

在這種情況下,我希望輸出為'Erwinia'。

謝謝你的幫助。

找到交叉點,然后重新獲得訂單。

intersection_set = set.intersection(*map(set, taxa))
intersection_lst = [t for t in taxa[0] if t in intersection_set]

或者,如果你非常喜歡單行:

sorted(set.intersection(*map(set, taxa)), key=lambda x: taxa[0].index(x))

您可以通過以下方式獲得:

[t for t in taxa[0] if all(t in l for l in taxa)]
# ['Bacteria', 'Proteobacteria', 'Gammaproteobacteria', 'Enterobacteriales', 'Enterobacteriaceae', 'Erwinia']

如果列表很大,那么執行效率會更高:

taxa_set = map(set, taxa)    
[t for t in taxa[0] if all(t in l for l in taxa_set)]
from collections import OrderedDict
from itertools import chain

d=OrderedDict()
for elem in chain(*taxa):
    if elem in d:
        d[elem] += 1
    else:
        d[elem] = 1

intersection_lst = [ k for k,v in d.items() if v == len(taxa) ]

請注意,這僅在內部列表是唯一的情況下才有效。

以下是使用有序計數器的示例:

from collections import OrderedDict,Counter
from itertools import chain

class OrderedCounter(Counter,OrderedDict): pass

d = OrderedCounter(chain(*taxa))
intersection_lst = [ k for k,v in d.items() if v == len(taxa) ]

如果元素在每個子列表中都是唯一的,則仍然有效

我今天遇到了類似的問題。 在我的基准測試中,使用set.intersection是在CPython中實現這一目標的最快方法,使用我的數據集需要大約170us。

然而,在PyPy中,利用排序的手動功能只需要大約80us, 幾乎是CPython速度的兩倍 CPython中的相同功能花費了大約6200us。

這是后人的功能:

def intersect_ordered(a, b):
    matches = []
    ia, ib = 0, 0
    la, lb = len(a), len(b)
    while ia < la and ib < lb:
        va, vb = a[ia], b[ib]
        if va < vb:
            ia += 1
        elif vb < va:
            ib += 1
        else:
            matches.append(va)
            ia += 1
            ib += 1
    return matches

暫無
暫無

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

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