2012-08-14 19 views
8

आदेश को बनाए रखते हुए नेस्टेड सूचियों के बीच छेड़छाड़ करना चाहूंगा।पायथन: नेस्टेड सूचियों का चौराहे जहां आदेश

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']) 

मूल रूप से, मैं क्या करने की जरूरत है नेस्टेड सूची (वे taxanomic वर्गीकरण हैं) के बीच पिछले आम तत्व लगता है। तो मुझे सभी चौराहे खोजने की ज़रूरत नहीं है, केवल आखिरी एक या उन सभी को जब मैं अंतिम प्रविष्टि पर कॉल कर सकता हूं।

intersection_lst[-1] 

इस उदाहरण में मैं आउटपुट 'इरविनिया' होना चाहता हूं।

आपकी मदद के लिए धन्यवाद।

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

सूचियों बड़े हैं, तो यह करने के लिए और अधिक कुशल हो जाएगा:

+0

अजगर के किस संस्करण के साथ काम कर रहे हैं:

यहाँ भावी पीढ़ी के लिए है कि समारोह है? –

+0

संस्करण पायथन 2.7.3 – Binnie

उत्तर

7

चौराहे का पता लगाएं में अद्वितीय हैं, तो आदेश reimpose:

और यहाँ एक आदेश दिया काउंटर का उपयोग कर एक उदाहरण है।

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)) 
+0

यह सही है! धन्यवाद! – Binnie

0

आप के साथ इस प्राप्त कर सकते हैं

taxa_set = map(set, taxa)  
[t for t in taxa[0] if all(t in l for l in taxa_set)] 
0
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) ] 

काम करता है, तो तत्व एक sublist

+0

यह काम नहीं करेगा यदि एक तत्व आंतरिक सूची में कई बार प्रकट होता है। –

+0

@ डेविड रॉबिन्सन - अच्छा बिंदु, मैंने इसके बारे में सोचा नहीं था। – mgilson

0

मैं आज एक ऐसी ही समस्या थी। मेरे बेंचमार्क में, set.intersection का उपयोग करके सीपीथॉन में इसे प्राप्त करने का सबसे तेज़ तरीका था, जो मेरे डेटासेट के साथ ~ 170US ले रहा था।

पीईपीई में हालांकि, आदेश के लाभ लेने वाले हाथ से चलने वाले फ़ंक्शन ने केवल 8080, को लगभग सीपीथॉन की गति को दोगुना कर दिया! सीपीथॉन में एक ही समारोह ~ 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 
संबंधित मुद्दे