सूची चौराहा कैसे खोजें?


203
a = [1,2,3,4,5]
b = [1,3,5,6]
c = a and b
print c

वास्तविक आउटपुट: [1,3,5,6] अपेक्षित आउटपुट:[1,3,5]

हम दो सूचियों पर बूलियन एंड ऑपरेशन (सूची चौराहा) कैसे प्राप्त कर सकते हैं?


6
यहाँ समस्या यह है कि प्रलेखन सेa and b निम्न कथन की तरह काम करता है, इसमें उल्लेख किया गया है: " अभिव्यक्ति x and yपहले मूल्यांकन करती है x; यदि xगलत है, तो इसका मूल्य वापस आ गया है, अन्यथा, yमूल्यांकन किया जाता है और परिणामी मूल्य वापस आ जाता है। "
टेडेक

जवाबों:


347

यदि आदेश महत्वपूर्ण नहीं है और आपको डुप्लिकेट के बारे में चिंता करने की आवश्यकता नहीं है तो आप सेट चौराहे का उपयोग कर सकते हैं:

>>> a = [1,2,3,4,5]
>>> b = [1,3,5,6]
>>> list(set(a) & set(b))
[1, 3, 5]

9
क्या हुआ अगर a = [1,1,2,3,4,5]और b = [1,1,3,5,6]फिर चौराहे है [1,1,3,5]लेकिन उपरोक्त विधि द्वारा यह परिणाम होगा केवल एक ही 1यानी [1, 3, 5]क्या लिखने जिस तरह से यह तो ऐसा करने के लिए किया जाएगा?
नितीश कुमार पाल

6
@NItishKumarPal intersectionआमतौर पर समझा जाता है सेट आधारित। आप थोड़े अलग जानवर की तलाश कर रहे हैं - और आपको प्रत्येक सूची को क्रमबद्ध करके और परिणामों को मर्ज करके और विलय में द्वैध रखने की आवश्यकता हो सकती है।
जवदाबा

1
@ मार्कर्स यह डुप्लिकेट afaict नहीं होगा ।
जावदबा

84

सूची बोध का उपयोग करना मेरे लिए बहुत स्पष्ट है। प्रदर्शन के बारे में निश्चित नहीं है, लेकिन कम से कम चीजें सूची में रहती हैं।

[x for x in a if x in b]

या "सभी एक्स मान जो ए में हैं, यदि एक्स मान बी में है"।


1
यह सबसे अजगर है जो आदेश रखता है। यकीन नहीं क्यों यह उच्च उत्कीर्ण नहीं है !! महान समाधान के लिए thx!
बिल डी

15
यह एक O (n ^ 2) समाधान है, जबकि ऊपर दिए गए समाधान O (n) हैं
nareddyt

3
@nareddyt - bएक सेट बनाएं और आपके पास O (n)
jcchuks

2
@jcchuks इस समाधान का लाभ आपको डुप्लिकेट को बनाए रखने की आवश्यकता है। यदि आप विशिष्टता के बारे में सुनिश्चित हो सकते हैं, तो एक ओ (एन) सेट समाधान बेहतर होगा। हालाँकि, यदि डुप्लिकेट संभव नहीं है, तो ओपी भी सूचियों के बारे में बात क्यों कर रहा है? सूची चौराहे की धारणा एक गणितीय
गैरबराबरी है

63

यदि आप दो सूचियों में से बड़े को एक सेट में परिवर्तित करते हैं, तो आप किसी भी उपयोग के साथ उस सेट के प्रतिच्छेदन को प्राप्त कर सकते हैं intersection():

a = [1,2,3,4,5]
b = [1,3,5,6]
set(a).intersection(b)

9
क्या यह किसी से अलग हैlist(set(a) & set(b))
user1767754

3
यह क्यों मायने रखता है कि कौन सी सूची सेट करने के लिए परिवर्तित हो जाती है (मान = n)! केवल एक सेट करने के लिए परिवर्तित करने का क्या फायदा है?
3pitt

1
ऐसा लगता है कि तेजी से होगा
नाथन

29

बड़े से एक सेट बनाएं:

_auxset = set(a)

फिर,

c = [x for x in b if x in _auxset]

आप जो चाहते हैं वह करेंगे ( bआदेश को aसंरक्षित कर रहे हैं, जरूरी नहीं - दोनों को संरक्षित नहीं कर सकते ) और इसे तेजी से करें । ( if x in aसूची समझ में शर्त के रूप में उपयोग करना भी काम करेगा, और निर्माण की आवश्यकता से बचें _auxset, लेकिन दुर्भाग्य से पर्याप्त लंबाई की सूचियों के लिए यह बहुत धीमा होगा)।

यदि आप चाहते हैं कि परिणाम को क्रमबद्ध किया जाए, तो सूची के क्रम को बनाए रखने के बजाय, एक समान तरीका भी हो सकता है:

c = sorted(set(a).intersection(b))

यह लगभग निश्चित रूप से स्वीकृत उत्तर की तुलना में धीमा है लेकिन इसका फायदा है कि डुप्लिकेट खो नहीं जाते हैं।
ट्रिपल

18

यहां कुछ पायथन 2 / पायथन 3 कोड हैं जो दो सूचियों के चौराहे को खोजने के लिए सूची-आधारित और सेट-आधारित दोनों तरीकों के लिए समय की जानकारी उत्पन्न करते हैं।

शुद्ध सूची बोधक एल्गोरिदम O (n ^ 2) हैं, क्योंकि inसूची में एक रैखिक खोज है। सेट-आधारित एल्गोरिदम O (n) हैं, क्योंकि सेट खोज O (1) है, और सेट निर्माण O (n) है (और सेट को किसी सूची में परिवर्तित करना भी O (n) है)। तो पर्याप्त रूप से बड़े n के लिए सेट-आधारित एल्गोरिदम तेज़ हैं, लेकिन छोटे n के लिए सेट बनाने के ओवरहेड्स उन्हें शुद्ध सूची COMP एल्गोरिदम की तुलना में धीमा बनाते हैं।

#!/usr/bin/env python

''' Time list- vs set-based list intersection
    See http://stackoverflow.com/q/3697432/4014959
    Written by PM 2Ring 2015.10.16
'''

from __future__ import print_function, division
from timeit import Timer

setup = 'from __main__ import a, b'
cmd_lista = '[u for u in a if u in b]'
cmd_listb = '[u for u in b if u in a]'

cmd_lcsa = 'sa=set(a);[u for u in b if u in sa]'

cmd_seta = 'list(set(a).intersection(b))'
cmd_setb = 'list(set(b).intersection(a))'

reps = 3
loops = 50000

def do_timing(heading, cmd, setup):
    t = Timer(cmd, setup)
    r = t.repeat(reps, loops)
    r.sort()
    print(heading, r)
    return r[0]

m = 10
nums = list(range(6 * m))

for n in range(1, m + 1):
    a = nums[:6*n:2]
    b = nums[:6*n:3]
    print('\nn =', n, len(a), len(b))
    #print('\nn = %d\n%s %d\n%s %d' % (n, a, len(a), b, len(b)))
    la = do_timing('lista', cmd_lista, setup) 
    lb = do_timing('listb', cmd_listb, setup) 
    lc = do_timing('lcsa ', cmd_lcsa, setup)
    sa = do_timing('seta ', cmd_seta, setup)
    sb = do_timing('setb ', cmd_setb, setup)
    print(la/sa, lb/sa, lc/sa, la/sb, lb/sb, lc/sb)

उत्पादन

n = 1 3 2
lista [0.082171916961669922, 0.082588911056518555, 0.0898590087890625]
listb [0.069530963897705078, 0.070394992828369141, 0.075379848480224609]
lcsa  [0.11858987808227539, 0.1188349723815918, 0.12825107574462891]
seta  [0.26900982856750488, 0.26902294158935547, 0.27298116683959961]
setb  [0.27218389511108398, 0.27459001541137695, 0.34307217597961426]
0.305460649521 0.258469975867 0.440838458259 0.301898526833 0.255455833892 0.435697630214

n = 2 6 4
lista [0.15915989875793457, 0.16000485420227051, 0.16551494598388672]
listb [0.13000702857971191, 0.13060092926025391, 0.13543915748596191]
lcsa  [0.18650484085083008, 0.18742108345031738, 0.19513416290283203]
seta  [0.33592700958251953, 0.34001994132995605, 0.34146714210510254]
setb  [0.29436492919921875, 0.2953648567199707, 0.30039691925048828]
0.473793098554 0.387009751735 0.555194537893 0.540689066428 0.441652573672 0.633583767462

n = 3 9 6
lista [0.27657914161682129, 0.28098297119140625, 0.28311991691589355]
listb [0.21585917472839355, 0.21679902076721191, 0.22272896766662598]
lcsa  [0.22559309005737305, 0.2271728515625, 0.2323150634765625]
seta  [0.36382699012756348, 0.36453008651733398, 0.36750602722167969]
setb  [0.34979605674743652, 0.35533690452575684, 0.36164689064025879]
0.760194128313 0.59330170819 0.62005595016 0.790686848184 0.61710008036 0.644927481902

n = 4 12 8
lista [0.39616990089416504, 0.39746403694152832, 0.41129183769226074]
listb [0.33485794067382812, 0.33914685249328613, 0.37850618362426758]
lcsa  [0.27405810356140137, 0.2745978832244873, 0.28249192237854004]
seta  [0.39211201667785645, 0.39234519004821777, 0.39317893981933594]
setb  [0.36988520622253418, 0.37011313438415527, 0.37571001052856445]
1.01034878821 0.85398540833 0.698928091731 1.07106176249 0.905302334456 0.740927452493

n = 5 15 10
lista [0.56792402267456055, 0.57422614097595215, 0.57740211486816406]
listb [0.47309303283691406, 0.47619009017944336, 0.47628307342529297]
lcsa  [0.32805585861206055, 0.32813096046447754, 0.3349759578704834]
seta  [0.40036201477050781, 0.40322518348693848, 0.40548801422119141]
setb  [0.39103078842163086, 0.39722800254821777, 0.43811702728271484]
1.41852623806 1.18166313332 0.819398061028 1.45237674242 1.20986133789 0.838951479847

n = 6 18 12
lista [0.77897095680236816, 0.78187918663024902, 0.78467702865600586]
listb [0.629547119140625, 0.63210701942443848, 0.63321495056152344]
lcsa  [0.36563992500305176, 0.36638498306274414, 0.38175487518310547]
seta  [0.46695613861083984, 0.46992206573486328, 0.47583580017089844]
setb  [0.47616910934448242, 0.47661614418029785, 0.4850609302520752]
1.66818870637 1.34819326075 0.783028414812 1.63591241329 1.32210827369 0.767878297495

n = 7 21 14
lista [0.9703209400177002, 0.9734041690826416, 1.0182771682739258]
listb [0.82394003868103027, 0.82625699043273926, 0.82796716690063477]
lcsa  [0.40975093841552734, 0.41210508346557617, 0.42286920547485352]
seta  [0.5086359977722168, 0.50968098640441895, 0.51014018058776855]
setb  [0.48688101768493652, 0.4879908561706543, 0.49204087257385254]
1.90769222837 1.61990115188 0.805587768483 1.99293236904 1.69228211566 0.841583309951

n = 8 24 16
lista [1.204819917678833, 1.2206029891967773, 1.258256196975708]
listb [1.014998197555542, 1.0206191539764404, 1.0343101024627686]
lcsa  [0.50966787338256836, 0.51018595695495605, 0.51319599151611328]
seta  [0.50310111045837402, 0.50556015968322754, 0.51335406303405762]
setb  [0.51472997665405273, 0.51948785781860352, 0.52113485336303711]
2.39478683834 2.01748351664 1.01305257092 2.34068341135 1.97190418975 0.990165516871

n = 9 27 18
lista [1.511646032333374, 1.5133969783782959, 1.5639569759368896]
listb [1.2461750507354736, 1.254518985748291, 1.2613379955291748]
lcsa  [0.5565330982208252, 0.56119203567504883, 0.56451296806335449]
seta  [0.5966339111328125, 0.60275578498840332, 0.64791703224182129]
setb  [0.54694414138793945, 0.5508568286895752, 0.55375313758850098]
2.53362406013 2.08867620074 0.932788243907 2.76380331728 2.27843203069 1.01753187594

n = 10 30 20
lista [1.7777848243713379, 2.1453688144683838, 2.4085969924926758]
listb [1.5070111751556396, 1.5202279090881348, 1.5779800415039062]
lcsa  [0.5954139232635498, 0.59703707695007324, 0.60746097564697266]
seta  [0.61563014984130859, 0.62125110626220703, 0.62354087829589844]
setb  [0.56723213195800781, 0.57257509231567383, 0.57460403442382812]
2.88774814689 2.44791645689 0.967161734066 3.13413984189 2.6567803378 1.04968299523

लिनक्स के एक डेबियन स्वाद (पृष्ठभूमि में चल रहे फ़ायरफ़ॉक्स के साथ) पर 2 जीबी रैम के साथ 2GHz सिंगल कोर मशीन का उपयोग करके उत्पन्न किया गया है।

ये आंकड़े केवल एक मोटे गाइड हैं, क्योंकि विभिन्न एल्गोरिदम की वास्तविक गति उन तत्वों के अनुपात से भिन्न रूप से प्रभावित होती है जो दोनों स्रोत सूचियों में हैं।


11
a = [1,2,3,4,5]
b = [1,3,5,6]
c = list(set(a).intersection(set(b)))

सपने की तरह काम करना चाहिए। और, यदि आप इस प्रकार के परिवर्तन से बचने के लिए सूचियों के बजाय सेट का उपयोग कर सकते हैं!


यदि a और b बड़े हैं तो यह अन्य उत्तरों की तुलना में तेज़ है
javadba

5

एक कार्यात्मक तरीका का उपयोग करके filterऔर lambdaऑपरेटर को प्राप्त किया जा सकता है ।

list1 = [1,2,3,4,5,6]

list2 = [2,4,6,9,10]

>>> list(filter(lambda x:x in list1, list2))

[2, 4, 6]

संपादित करें: यह x को फ़िल्टर करता है जो सूची 1 और सूची दोनों में मौजूद है, सेट अंतर का उपयोग करके भी प्राप्त किया जा सकता है:

>>> list(filter(lambda x:x not in list1, list2))
[9,10]

Edit2: python3 filterएक फ़िल्टर ऑब्जेक्ट देता है, इसे listआउटपुट लिस्ट के साथ एन्क्रिप्ट करता है ।


यह कोड कैसे काम करता है यह समझाने के लिए कृपया संपादन लिंक का उपयोग करें और केवल कोड न दें, क्योंकि स्पष्टीकरण में भविष्य के पाठकों की मदद करने की अधिक संभावना है। इसका जवाब भी देखें । स्रोत
जेड फॉक्स

1
Python3 के साथ, यह एक फ़िल्टर ऑब्जेक्ट देता है। आपको list(filter(lambda x:x in list1, list2))इसे एक सूची के रूप में प्राप्त करने के लिए कहने की आवश्यकता है ।
एड्रियन डब्ल्यू

1

यह एक उदाहरण है जब आपको आवश्यकता होती है परिणाम में प्रत्येक तत्व को कई बार दिखाई देना चाहिए जैसा कि दोनों सरणियों में दिखाया गया है।

def intersection(nums1, nums2):
    #example:
    #nums1 = [1,2,2,1]
    #nums2 = [2,2]
    #output = [2,2]
    #find first 2 and remove from target, continue iterating

    target, iterate = [nums1, nums2] if len(nums2) >= len(nums1) else [nums2, nums1] #iterate will look into target

    if len(target) == 0:
            return []

    i = 0
    store = []
    while i < len(iterate):

         element = iterate[i]

         if element in target:
               store.append(element)
               target.remove(element)

         i += 1


    return store

1

यह देर हो सकती है लेकिन मुझे लगा कि मुझे उस मामले के लिए साझा करना चाहिए जहां आपको इसे मैन्युअल रूप से करने की आवश्यकता है (काम करना - हाहा) या जब आपको सभी तत्वों को जितनी बार संभव हो या जब आपको अद्वितीय होने की आवश्यकता हो ।

कृपया ध्यान दें कि इसके लिए परीक्षण भी लिखे गए हैं।



    from nose.tools import assert_equal

    '''
    Given two lists, print out the list of overlapping elements
    '''

    def overlap(l_a, l_b):
        '''
        compare the two lists l_a and l_b and return the overlapping
        elements (intersecting) between the two
        '''

        #edge case is when they are the same lists
        if l_a == l_b:
            return [] #no overlapping elements

        output = []

        if len(l_a) == len(l_b):
            for i in range(l_a): #same length so either one applies
                if l_a[i] in l_b:
                    output.append(l_a[i])

            #found all by now
            #return output #if repetition does not matter
            return list(set(output))

        else:
            #find the smallest and largest lists and go with that
            sm = l_a if len(l_a)  len(l_b) else l_b

            for i in range(len(sm)):
                if sm[i] in lg:
                    output.append(sm[i])

            #return output #if repetition does not matter
            return list(set(output))

    ## Test the Above Implementation

    a = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
    b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
    exp = [1, 2, 3, 5, 8, 13]

    c = [4, 4, 5, 6]
    d = [5, 7, 4, 8 ,6 ] #assuming it is not ordered
    exp2 = [4, 5, 6]

    class TestOverlap(object):

        def test(self, sol):
            t = sol(a, b)
            assert_equal(t, exp)
            print('Comparing the two lists produces')
            print(t)

            t = sol(c, d)
            assert_equal(t, exp2)
            print('Comparing the two lists produces')
            print(t)

            print('All Tests Passed!!')

    t = TestOverlap()
    t.test(overlap)

0

यदि, बूलियन और, आप का मतलब है कि आइटम दोनों सूचियों में दिखाई देते हैं, जैसे चौराहे, तो आपको पायथन setऔर frozensetप्रकारों को देखना चाहिए ।


0

आप एक काउंटर का उपयोग भी कर सकते हैं! यह आदेश को संरक्षित नहीं करता है, लेकिन यह डुप्लिकेट पर विचार करेगा:

>>> from collections import Counter
>>> a = [1,2,3,4,5]
>>> b = [1,3,5,6]
>>> d1, d2 = Counter(a), Counter(b)
>>> c = [n for n in d1.keys() & d2.keys() for _ in range(min(d1[n], d2[n]))]
>>> print(c)
[1,3,5]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.