2 सूचियों के बीच तुलना करने वाले सामान्य तत्व


143
def common_elements(list1, list2):
    """
    Return a list containing the elements which are in both list1 and list2

    >>> common_elements([1,2,3,4,5,6], [3,5,7,9])
    [3, 5]
    >>> common_elements(['this','this','n','that'],['this','not','that','that'])
    ['this', 'that']
    """
    for element in list1:
        if element in list2:
            return list(element)

अब तक मिल गया है, लेकिन यह काम करने के लिए नहीं मिल सकता है!

कोई विचार?


1
नमस्ते, क्या आप कोड का उपयोग करने की योजना के बारे में कुछ विवरण जोड़ सकते हैं? यदि यह एक असाइनमेंट पूरा करना है, तो एक समाधान चुनना बेहतर हो सकता है जो "पायथोनिक" तरीके को एनकैप्सुलेट करता है। हालांकि, अगर दक्षता आपकी चिंता है, तो "पायथोनिक" तरीका सबसे कुशल समाधान होने की संभावना नहीं है। इन विवरणों पर हमें सलाह देने से आपकी समस्या का समाधान करने में मदद मिलेगी।
मैट सी

जवाबों:


278
>>> list1 = [1,2,3,4,5,6]
>>> list2 = [3, 5, 7, 9]
>>> list(set(list1).intersection(list2))
[3, 5]

1
+1 लेकिन मैं व्यक्तिगत रूप से फ्रोज़ेन्सेट का उपयोग करूंगा क्योंकि यह अपरिवर्तनीय है और इसलिए इसे शब्दकोश कुंजी आदि के रूप में इस्तेमाल किया जा सकता है
zebrabox

19
यह / अद्वितीय / सामान्य तत्वों को लौटाएगा, लेकिन किसी भी दोहराए जाने वाले तत्वों का अस्तित्व नहीं होगा।
Dologan

@SilentGhost। दो सूची से मिलान तत्वों की संख्या कैसे प्राप्त करें। इस मामले में यह 2. है
पोका

@ पोका लेन (सूची (सेट 1)) .intersection (सूची 2))
धर्मांशु कामरा

2
FYI करें। तामसे द्वारा प्रस्तावित समाधान की तुलना में यह निश्चित रूप से तेज है, लेकिन इस पृष्ठ पर समाप्त होने पर मैं जिस उपयोग के मामले को देख रहा था, उसके लिए तत्वों को फ़िल्टर करने के बाद तत्वों के मूल क्रम को संरक्षित करना महत्वपूर्ण था। यह विधि आदेश खो देती है, जबकि सूची समझने की विधि आदेश को संरक्षित करती है। यदि किसी को इस पर विचार करने की आवश्यकता है तो महत्वपूर्ण है। धन्यवाद।
तारीख

41

आप सेट का उपयोग भी कर सकते हैं और एक पंक्ति में समानताएं प्राप्त कर सकते हैं: सेट को किसी एक सेट से अंतर से घटाएं।

A = [1,2,3,4]
B = [2,4,7,8]
commonalities = set(A) - (set(A) - set(B))

4
यह ए को दो बार सेट करने के लिए परिवर्तित करता है, अनावश्यक रूप से बेकार।
विम

36

S.Mark और SilentGhost द्वारा सुझाए गए समाधान आम तौर पर आपको बताते हैं कि इसे पायथोनिक तरीके से कैसे किया जाना चाहिए, लेकिन मैंने सोचा कि आपको यह जानकर भी फायदा हो सकता है कि आपका समाधान काम क्यों नहीं करता है। समस्या यह है कि जैसे ही आप दो सूचियों में पहला सामान्य तत्व ढूंढते हैं, आप केवल उस एकल तत्व को वापस करते हैं। आपका समाधान एक resultसूची बनाकर और उस सूची में आम तत्वों को एकत्रित करके तय किया जा सकता है :

def common_elements(list1, list2):
    result = []
    for element in list1:
        if element in list2:
            result.append(element)
    return result

सूची बोध का उपयोग करते हुए एक छोटा संस्करण:

def common_elements(list1, list2):
    return [element for element in list1 if element in list2]

हालाँकि, जैसा कि मैंने कहा, यह ऐसा करने का एक बहुत ही अक्षम तरीका है - पायथन के अंतर्निहित सेट प्रकार अधिक कुशल हैं क्योंकि वे आंतरिक रूप से सी में लागू होते हैं।


1
दोनों प्रस्तावों के लिए महान
dlewin

1
नोट: उपरोक्त विधियाँ केवल समान आकार की सूचियों के लिए काम करेंगी। यदि आप असमान आकार की सूचियों के साथ काम कर रहे हैं, जैसा कि मैं हूं, तो आपको फ़ंक्शन को कॉल करने से पहले लेन () पर आधारित आदेश का मूल्यांकन करने की आवश्यकता होगी: सूची 1 = [2,2,2], सूची 2 [2,3] -> [२,२,२] सूची १ = [२,३], सूची २ [२,२,२] -> [२]
११

29

सेट चौराहों, सेट (सूची 1) और सेट (सूची 2) का उपयोग करें

>>> def common_elements(list1, list2):
...     return list(set(list1) & set(list2))
...
>>>
>>> common_elements([1,2,3,4,5,6], [3,5,7,9])
[3, 5]
>>>
>>> common_elements(['this','this','n','that'],['this','not','that','that'])
['this', 'that']
>>>
>>>

ध्यान दें कि परिणाम सूची मूल सूची के साथ अलग-अलग क्रम हो सकती है।


सहायता के लिए धन्यवाद। समझें कि मैं कहां गलत हो गया और अगली बार क्या काम करना है। :)
डैनियल

5
महान समाधान। क्या इसके साथ आदेश को संरक्षित करने का कोई तरीका है?
टार्च


9

सेट एक और तरीका है जिससे हम इसे हल कर सकते हैं

a = [3,2,4]
b = [2,3,5]
set(a)&set(b)
{2, 3}

9

सूची 1 = [1,2,3,4,5,6] सूची 2 = [3,5,7,9]

मुझे पता है कि 3 तरीके इसे हल कर सकते हैं, ज़ाहिर है, और भी हो सकते हैं।

1-

common_elements = [e for e in list1 if e in list2]

2-

import numpy as np
common_elements = np.intersect1d(list1, list2)

3-

common_elements = set(list1).intersection(list2)

तीसरा तरीका सबसे तेज़ है क्योंकि सेट को हैश टेबल का उपयोग करके लागू किया जाता है।


8

पिछले उत्तर सभी अद्वितीय तत्वों को खोजने के लिए काम करते हैं, लेकिन सूचियों में दोहराया वस्तुओं के लिए खाते में विफल रहेंगे। यदि आप चाहते हैं कि समान तत्व समान संख्या में दिखाई दें जैसा कि वे सूचियों में सामान्य रूप से पाए जाते हैं, तो आप निम्न एक-लाइनर का उपयोग कर सकते हैं:

l2, common = l2[:], [ e for e in l1 if e in l2 and (l2.pop(l2.index(e)) or True)]

or Trueयदि आप करने के लिए मूल्यांकन करने के लिए किसी भी तत्व को उम्मीद हिस्सा केवल आवश्यक है False


विस्मयकारी समाधान, सबसे अच्छी तरह से लगता है, अगर थोड़ा सा
प्रवृत्त

यह उत्तर होना चाहिए जो चुना जाना चाहिए था! मैं यह मान रहा हूं कि यह असमान सूचियों के लिए भी काम करता है। इसके अलावा अधिकांश समाधानों का उपयोग setहोता है जो स्थिर नहीं है (उर्फ आदेश खो गया है)।
जीवनदायिनी

7

मैंने प्रत्येक विधि की तुलना की जिसका प्रत्येक उत्तर में उल्लेख है। इस समय मैं इस कार्यान्वयन के लिए अजगर 3.6.3 का उपयोग करता हूं। यह वह कोड है जिसका मैंने उपयोग किया है:

import time
import random
from decimal import Decimal


def method1():
    common_elements = [x for x in li1_temp if x in li2_temp]
     print(len(common_elements))


def method2():
    common_elements = (x for x in li1_temp if x in li2_temp)
    print(len(list(common_elements)))


def method3():
    common_elements = set(li1_temp) & set(li2_temp)
    print(len(common_elements))


def method4():
    common_elements = set(li1_temp).intersection(li2_temp)
    print(len(common_elements))


if __name__ == "__main__":
    li1 = []
    li2 = []
    for i in range(100000):
        li1.append(random.randint(0, 10000))
        li2.append(random.randint(0, 10000))

    li1_temp = list(set(li1))
    li2_temp = list(set(li2))

    methods = [method1, method2, method3, method4]
    for m in methods:
        start = time.perf_counter()
        m()
        end = time.perf_counter()
        print(Decimal((end - start)))

यदि आप इस कोड को चलाते हैं, तो आप देख सकते हैं कि यदि आप सूची या जनरेटर का उपयोग करते हैं (यदि आप जनरेटर पर पुनरावृति करते हैं, तो इसका उपयोग न करें। मैंने ऐसा तब किया था जब मैंने जनरेटर को इसकी लंबाई प्रिंट करने के लिए मजबूर किया था), आपको लगभग समान प्रदर्शन मिलता है। लेकिन अगर आप सेट का उपयोग करते हैं तो आपको बेहतर प्रदर्शन मिलता है। इसके अलावा अगर आप चौराहे की विधि का उपयोग करते हैं तो आपको थोड़ा बेहतर प्रदर्शन मिलेगा। मेरे कंप्यूटर में प्रत्येक विधि का परिणाम सूचीबद्ध है:

  1. Method1: 0.8150673999999999974619413478649221360683441
  2. Method2: 0.8329545000000001531148541289439890533685684
  3. Method3: 0.0016547000000000089414697868051007390022277
  4. Method4: 0.0010262999999999244948867271887138485908508

5

यह मेरा प्रस्ताव है कि मुझे लगता है कि यह लूप के लिए सेट की तुलना में आसान है

def unique_common_items(list1, list2):
   # Produce the set of *unique* common items in two lists.
   return list(set(list1) & set(list2))

2

उपयोग क्यों नहीं list comprehension?

आधा लाइन समाधान:

common_elements = [x for x in list1 if x in list2]

0

1) मेथड 1 सेविंग लिस्ट 1 डिक्शनरी है और फिर लिस्ट 2 में प्रत्येक एलिमेट को पुनरावृत्त करना है

def findarrayhash(a,b):
    h1={k:1 for k in a}
    for val in b:
        if val in h1:
            print("common found",val)
            del h1[val]
        else:
            print("different found",val)
    for key in h1.iterkeys():
        print ("different found",key)

सामान्य और विभिन्न तत्वों का पता लगाना:

2) Method2 सेट का उपयोग कर

def findarrayset(a,b):
    common = set(a)&set(b)
    diff=set(a)^set(b)
    print list(common)
    print list(diff) 

-1

एक जनरेटर का उपयोग करें:

common = (x for x in list1 if x in list2)

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

उदाहरण के लिए,

list1 =  list(range(0,10000000))
list2=list(range(1000,20000000))
common = (x for x in list1 if x in list2)

यहाँ अन्य सभी उत्तर सूची 1 और सूची 2 के लिए इन मूल्यों के साथ बहुत लंबा समय लेंगे।

आप इसके बाद उत्तर को पुन: लिख सकते हैं

for i in common: print(i)

या के साथ एक सूची में परिवर्तित करें

list(i)

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

1
सही है, यह एक जनरेटर बनाता है, जो एक उत्तर है। प्रश्न किसी तरह 2 सूचियों के सामान्य तत्वों को प्राप्त करना था, जो यह जनरेटर करता है। बस जनरेटर की तरह iterate for i in common: print(i):। जनरेटर पुनरावृत्तियाँ हैं जिन्हें अक्सर अन्य पुनरावृत्तियों जैसे सूचियों के स्थान पर उपयोग किया जाता है।
काउलिनेटर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.