[Python] दो नेस्टेड सूचियों का चौराहे खोजें?



Answers

आपको चौराहे को परिभाषित करने की आवश्यकता नहीं है। यह पहले से ही सेट का प्रथम श्रेणी का हिस्सा है।

>>> b1 = [1,2,3,4,5,9,11,15]
>>> b2 = [4,5,6,7,8]
>>> set(b1).intersection(b2)
set([4, 5])
Question

मुझे पता है कि दो फ्लैट सूचियों का एक चौराहे कैसे प्राप्त करें:

b1 = [1,2,3,4,5,9,11,15]
b2 = [4,5,6,7,8]
b3 = [val for val in b1 if val in b2]

या

def intersect(a, b):
    return list(set(a) & set(b))

print intersect(b1, b2)

लेकिन जब मुझे नेस्टेड सूचियों के लिए छेड़छाड़ मिलनी है तो मेरी समस्याएं शुरू होती हैं:

c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]

अंत में मैं प्राप्त करना चाहता हूं:

c3 = [[13,32],[7,13,28],[1,6]]

क्या आप लोग मुझे इसके साथ हाथ दे सकते हैं?

सम्बंधित




दिया हुआ:

> c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]

> c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]

मुझे लगता है कि निम्न कोड अच्छी तरह से काम करता है और सेट ऑपरेशन का उपयोग करते हुए शायद अधिक संक्षिप्त हो सकता है:

> c3 = [list(set(f)&set(c1)) for f in c2] 

इसे मिला:

> [[32, 13], [28, 13, 7], [1, 6]]

अगर आदेश की आवश्यकता है:

> c3 = [sorted(list(set(f)&set(c1))) for f in c2] 

हमें मिला:

> [[13, 32], [7, 13, 28], [1, 6]]

वैसे, एक और अजगर शैली के लिए, यह भी ठीक है:

> c3 = [ [i for i in set(f) if i in c1] for f in c2]



और ऑपरेटर दो सेटों का चौराहे लेता है।

{1, 2, 3} और {2, 3, 4} आउट [1]: {2, 3}




शुद्ध सूची समझ संस्करण

>>> c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
>>> c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]
>>> c1set = frozenset(c1)

Flatten संस्करण:

>>> [n for lst in c2 for n in lst if n in c1set]
[13, 32, 7, 13, 28, 1, 6]

नेस्टेड संस्करण:

>>> [[n for n in lst if n in c1set] for lst in c2]
[[13, 32], [7, 13, 28], [1, 6]]



आपको इस कोड का उपयोग करके फ़्लैट करना चाहिए ( http://kogs-www.informatik.uni-hamburg.de/~meine/python_tricks से लिया गया), कोड अनचाहे है, लेकिन मुझे पूरा यकीन है कि यह काम करता है:


def flatten(x):
    """flatten(sequence) -> list

    Returns a single, flat list which contains all elements retrieved
    from the sequence and all recursively contained sub-sequences
    (iterables).

    Examples:
    >>> [1, 2, [3,4], (5,6)]
    [1, 2, [3, 4], (5, 6)]
    >>> flatten([[[1,2,3], (42,None)], [4,5], [6], 7, MyVector(8,9,10)])
    [1, 2, 3, 42, None, 4, 5, 6, 7, 8, 9, 10]"""

    result = []
    for el in x:
        #if isinstance(el, (list, tuple)):
        if hasattr(el, "__iter__") and not isinstance(el, basestring):
            result.extend(flatten(el))
        else:
            result.append(el)
    return result

सूची को चपटा करने के बाद, आप सामान्य तरीके से छेड़छाड़ करते हैं:


c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]

def intersect(a, b):
     return list(set(a) & set(b))

print intersect(flatten(c1), flatten(c2))




हम इसके लिए सेट विधियों का उपयोग कर सकते हैं:

c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]

   result = [] 
   for li in c2:
       res = set(li) & set(c1)
       result.append(list(res))

   print result



मुझे नहीं पता कि मुझे आपके प्रश्न का उत्तर देने में देर हो चुकी है या नहीं। अपना प्रश्न पढ़ने के बाद मैं एक फ़ंक्शन intersect () के साथ आया जो सूची और नेस्टेड सूची दोनों पर काम कर सकता है। मैंने इस समारोह को परिभाषित करने के लिए रिकर्सन का उपयोग किया, यह बहुत सहज है। आशा है कि आप यही देख रहे हैं:

def intersect(a, b):
    result=[]
    for i in b:
        if isinstance(i,list):
            result.append(intersect(a,i))
        else:
            if i in a:
                 result.append(i)
    return result

उदाहरण:

>>> c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
>>> c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]
>>> print intersect(c1,c2)
[[13, 32], [7, 13, 28], [1, 6]]

>>> b1 = [1,2,3,4,5,9,11,15]
>>> b2 = [4,5,6,7,8]
>>> print intersect(b1,b2)
[4, 5]



चौराहे को परिभाषित करने के लिए जो सही ढंग से ध्यान में रखता है तत्वों की कार्डिनालिटी Counter उपयोग करता है:

from collections import Counter

>>> c1 = [1, 2, 2, 3, 4, 4, 4]
>>> c2 = [1, 2, 4, 4, 4, 4, 5]
>>> list((Counter(c1) & Counter(c2)).elements())
[1, 2, 4, 4, 4]



Links