मैं अजगर और वापसी मैचों में दो सूचियों की तुलना कैसे कर सकता हूं


379

मैं दो सूची लेना चाहता हूं और उन मूल्यों को खोजना चाहता हूं जो दोनों में दिखाई देते हैं।

a = [1, 2, 3, 4, 5]
b = [9, 8, 7, 6, 5]

returnMatches(a, b)

[5]उदाहरण के लिए, लौटेगा ।


4
नीचे दिए गए उत्तर मुझे गलत लगते हैं। यदि किसी सूची में कोई संख्या दोहराई जाती है, तो निश्चित रूप से आप यह जानना चाहते हैं कि (?) वह जानकारी।
MH

जवाबों:


486

सबसे कुशल एक नहीं है, लेकिन अभी तक यह करने का सबसे स्पष्ट तरीका है:

>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(a) & set(b)
{5}

यदि आदेश महत्वपूर्ण है, तो आप इसे इस तरह सूची बोध के साथ कर सकते हैं:

>>> [i for i, j in zip(a, b) if i == j]
[5]

(केवल समान आकार की सूचियों के लिए काम करता है, जो क्रम-महत्व का तात्पर्य है)।


15
सावधानी का एक नोट, सूची समझ है नहीं जरूरी तेजी से विकल्प। बड़े सेटों के लिए (जहाँ प्रदर्शन की सबसे अधिक संभावना है) बिटवाइज़ तुलना ( &) या set(a).intersection(b)सूची बोध की तुलना में तेज़ या तेज़ होगी।
जोशमेकर

24
सावधानी का एक और नोट: सूची की समझ उन मूल्यों को खोजती है जो एसएएमई पदों पर दोनों में दिखाई देती हैं (यह "ऑर्डर महत्वपूर्ण है" से साइलेंटगॉस्ट का मतलब है)। सेट चौराहे समाधान भी अलग-अलग पदों पर मैच पाएंगे। ये 2 काफी अलग-अलग सवालों के जवाब हैं ... (सेशन का सवाल अस्पष्ट है, जिससे यह पूछ रहा है)
drevicko

यदि आपकी सूचियाँ सूचियों अर्थात a = [[0,0], [1,0]] और b = [[2,3], [0,0]]
Schneems

3
पहले उदाहरण की समय जटिलता क्या होगी set(a) & set(b)?
एडजक्टप्रोफेसर फाल्कन

ध्यान दें, यह काम नहीं करता है यदि दोनों सेट खाली हैं और आप पास होने की तुलना करते हैं। तो "सेट (ए) और सेट (बी)) या (नहीं और बी नहीं)"
नील मैकगिल

395

Set.intersection () का उपयोग करें , यह तेज और पठनीय है।

>>> set(a).intersection(b)
set([5])

28
इस उत्तर में अच्छा एल्गोरिदमिक प्रदर्शन है, क्योंकि केवल एक सूची (छोटी को प्राथमिकता दी जानी चाहिए) त्वरित लुकअप के लिए एक सेट में बदल जाती है, और दूसरी सूची में सेट में अपने आइटम को देखने के लिए ट्रैवर्स किया जाता है।
u0b34a0f6ae 12

18
bool(set(a).intersection(b))के लिए TrueयाFalse
अक्षय

6
यह उत्तर अधिक लचीला और पठनीय है, क्योंकि लोगों को आवश्यकता हो सकती है differenceया union
शीह झांग

क्या होगा अगर मेरे पास सूची तत्वों के रूप में ऑब्जेक्ट हैं और केवल आंशिक मैच चाहते हैं, अर्थात, केवल कुछ विशेषताओं को मिलान करने वाली वस्तु के रूप में माना जाना है?
CGFoX

क्या .intersection()बनाम के लिए कोई प्रदर्शन अंतर है &?
ब्रैंडनबैंक 13

106

लुट्ज़ का समाधान दिखाने वाला एक त्वरित प्रदर्शन परीक्षण सबसे अच्छा है:

import time

def speed_test(func):
    def wrapper(*args, **kwargs):
        t1 = time.time()
        for x in xrange(5000):
            results = func(*args, **kwargs)
        t2 = time.time()
        print '%s took %0.3f ms' % (func.func_name, (t2-t1)*1000.0)
        return results
    return wrapper

@speed_test
def compare_bitwise(x, y):
    set_x = frozenset(x)
    set_y = frozenset(y)
    return set_x & set_y

@speed_test
def compare_listcomp(x, y):
    return [i for i, j in zip(x, y) if i == j]

@speed_test
def compare_intersect(x, y):
    return frozenset(x).intersection(y)

# Comparing short lists
a = [1, 2, 3, 4, 5]
b = [9, 8, 7, 6, 5]
compare_bitwise(a, b)
compare_listcomp(a, b)
compare_intersect(a, b)

# Comparing longer lists
import random
a = random.sample(xrange(100000), 10000)
b = random.sample(xrange(100000), 10000)
compare_bitwise(a, b)
compare_listcomp(a, b)
compare_intersect(a, b)

ये मेरी मशीन पर परिणाम हैं:

# Short list:
compare_bitwise took 10.145 ms
compare_listcomp took 11.157 ms
compare_intersect took 7.461 ms

# Long list:
compare_bitwise took 11203.709 ms
compare_listcomp took 17361.736 ms
compare_intersect took 6833.768 ms

जाहिर है, किसी भी कृत्रिम प्रदर्शन परीक्षण को नमक के एक दाने के साथ लिया जाना चाहिए, लेकिन चूंकि set().intersection()उत्तर कम से कम दूसरे समाधानों की तुलना में तेज है , और सबसे पठनीय भी है, यह इस सामान्य समस्या का मानक समाधान होना चाहिए।


सेट वास्तव में दोहराव को दूर कर रहा है, इसलिए मेरे मामले में अभ्यस्त काम
rralma

@rgralma setकिसी मौजूदा से नया बनाने listसे मूल से कुछ भी नहीं हटेगा list। यदि आप एक सूची के भीतर डुप्लिकेट को संभालने के लिए विशेष तर्क चाहते हैं, तो मुझे लगता है कि आपको एक नया प्रश्न पूछना होगा क्योंकि उत्तर के लिए विशिष्ट होना चाहिए कि आप डुप्लिकेट को कैसे संभालना चाहते हैं।
जोशमेकर

67

मैं सेट आधारित उत्तरों को पसंद करता हूं, लेकिन यहां एक है जो वैसे भी काम करता है

[x for x in a if x in b]



14
>>> s = ['a','b','c']   
>>> f = ['a','b','d','c']  
>>> ss= set(s)  
>>> fs =set(f)  
>>> print ss.intersection(fs)   
   **set(['a', 'c', 'b'])**  
>>> print ss.union(fs)        
   **set(['a', 'c', 'b', 'd'])**  
>>> print ss.union(fs)  - ss.intersection(fs)   
   **set(['d'])**

1
स्वीकृत उत्तर उन सूचियों के लिए काम नहीं करता है जिनमें तार होते हैं। यह एक करता है।
एंटनी

12

इसके अलावा, आप एक नई सूची में आम तत्वों को रखकर यह कोशिश कर सकते हैं।

new_list = []
for element in a:
    if element in b:
        new_list.append(element)

5

क्या आप डुप्लिकेट चाहते हैं? यदि नहीं तो आपको इसके बजाय सेट का उपयोग करना चाहिए:


>>> set([1, 2, 3, 4, 5]).intersection(set([9, 8, 7, 6, 5]))
set([5])

यदि आप वास्तव में सूचियाँ चाहते हैं, तो java2s.com/Code/Python/List/Functiontointersecttwolists.htm >>> प्रतिच्छेदन ([1, 2, 3, 4, 5], [9, 8, 7, 6, 5]] [5 ]
टिमोथी प्रथले

डॉक्स के अनुसार ... ... अधिक पठनीय सेट ('एबीसी') के पक्ष में सेट ('एबीसी') और 'सीबीएस' जैसे त्रुटि-प्रवण निर्माणों को रोकता है। - docs.python.org/library/sets.html
एरॉन न्यूटन

5

सूची 1 (lst1) और सूची 2 (lst2) के लिए सूची समानता की जांच करने के लिए एक और थोड़ा कार्यात्मक तरीका जहां वस्तुओं की गहराई एक है और जो क्रम रखता है वह है:

all(i == j for i, j in zip(lst1, lst2))   

4
a = [1, 2, 3, 4, 5]
b = [9, 8, 7, 6, 5]

lista =set(a)
listb =set(b)   
print listb.intersection(lista)   
returnMatches = set(['5']) #output 

print " ".join(str(return) for return in returnMatches ) # remove the set()   

 5        #final output 

हालांकि यह कोड प्रश्न का उत्तर दे सकता है, लेकिन समस्या को हल करने के तरीके के बारे में अतिरिक्त संदर्भ प्रदान करता है और यह समस्या को हल करता है ताकि उत्तर के दीर्घकालिक मूल्य में सुधार हो सके।
डोनाल्ड डक

4

Itertools.product का भी उपयोग कर सकते हैं।

>>> common_elements=[]
>>> for i in list(itertools.product(a,b)):
...     if i[0] == i[1]:
...         common_elements.append(i[0])


3

आप उपयोग कर सकते हैं:

a = [1, 3, 4, 5, 9, 6, 7, 8]
b = [1, 7, 0, 9]
same_values = set(a) & set(b)
print same_values

आउटपुट:

set([1, 7, 9])

4
यह ६+ साल पहले के स्वीकृत उत्तर से कैसे भिन्न है?
tmdavison

1
खैर, मैंने आउटपुट के साथ पूरा विवरण लिखा है और शुरुआती अजगर के लिए अच्छा है
अदनान गफ्फार

2

यदि आप एक बूलियन मूल्य चाहते हैं:

>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(b) == set(a)  & set(b) and set(a) == set(a) & set(b)
False
>>> a = [3,1,2]
>>> b = [1,2,3]
>>> set(b) == set(a)  & set(b) and set(a) == set(a) & set(b)
True

1

निम्नलिखित समाधान सूची मदों के किसी भी क्रम के लिए काम करता है और दोनों सूचियों को अलग-अलग लंबाई का समर्थन करता है।

import numpy as np
def getMatches(a, b):
    matches = []
    unique_a = np.unique(a)
    unique_b = np.unique(b)
    for a in unique_a:
        for b in unique_b:
            if a == b:
                matches.append(a)
    return matches
print(getMatches([1, 2, 3, 4, 5], [9, 8, 7, 6, 5, 9])) # displays [5]
print(getMatches([1, 2, 3], [3, 4, 5, 1])) # displays [1, 3]

1
Numpy के लिए एक विशिष्ट कार्य है:np.intersect1d(list1, list2)
15

0

__and__विशेषता विधि का उपयोग भी काम करता है।

>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(a).__and__(set(b))
set([5])

या केवल

>>> set([1, 2, 3, 4, 5]).__and__(set([9, 8, 7, 6, 5]))
set([5])
>>>    

0
you can | for set union and & for set intersection.
for example:

    set1={1,2,3}
    set2={3,4,5}
    print(set1&set2)
    output=3

    set1={1,2,3}
    set2={3,4,5}
    print(set1|set2)
    output=1,2,3,4,5

curly braces in the answer.

4
प्रश्न सूची और सेट के लिए नहीं था। &सेट पर ऑपरेटर का उपयोग पहले से ही स्वीकृत जवाब में साइलेंटगॉस्ट द्वारा उत्तर दिया गया है
dWinder

0

मैंने बस निम्नलिखित का उपयोग किया और यह मेरे लिए काम करता है:

group1 = [1, 2, 3, 4, 5]
group2 = [9, 8, 7, 6, 5]

for k in group1:
    for v in group2:
        if k == v:
            print(k)

यह तब आपके मामले में 5 प्रिंट करेगा। हालांकि महान प्रदर्शन बुद्धिमान नहीं है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.