यदि सूची में निम्नलिखित में से कोई एक वस्तु है, तो कैसे जांचें?


220

मैं यह देखने का एक छोटा तरीका ढूंढने की कोशिश कर रहा हूं कि निम्न में से कोई भी वस्तु सूची में है या नहीं, लेकिन मेरा पहला प्रयास काम नहीं करता है। इसे पूरा करने के लिए एक फ़ंक्शन लिखने के अलावा, यह जांचने का कोई छोटा तरीका है कि क्या एक से अधिक आइटम एक सूची में हैं।

>>> a = [2,3,4]
>>> print (1 or 2) in a
False
>>> print (2 or 1) in a
True

मजेदार बात, मैंने जाँच की कि कैसे 'और' व्यवहार करता है। a = [1, 2] b = [3, 5, 2, 6, 8, 9] c = [3, 5, 6, 8, 1, 9] print( (1 and 2) in b ,(2 and 1) in b ,(1 and 2) in c ,(2 and 1) in c, sep='\n')यह सच है झूठी झूठी है
पिओत्र कमोडा

जवाबों:


266
>>> L1 = [2,3,4]
>>> L2 = [1,2]
>>> [i for i in L1 if i in L2]
[2]


>>> S1 = set(L1)
>>> S2 = set(L2)
>>> S1.intersection(S2)
set([2])

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


6
चौराहे के विचार ने मुझे यह विचार दिया। रिटर्न लेन (सेट (a) .intersection (सेट (b)))
Deon

13
एफडब्ल्यूआईडब्ल्यू - मैंने एक गति तुलना की, और यहां पेश किया गया पहला समाधान अब तक उपवास था।
जैकीज़ाज़िल

2
@ user89788 का एक जनरेटर का उपयोग करने का उत्तर फिर से बहुत तेज है, क्योंकि anyजैसे ही यह Trueमूल्य पाता है, जल्दी वापस आ सकता है - इसके लिए पहले पूरी सूची नहीं
बनानी होगी

यदि आपके पास सूची में डुप्लिकेट हैं, तो दूसरा / सेट समाधान काम नहीं करेगा (जैसा कि सेट में प्रत्येक आइटम में से एक होता है)। यदि `L1 = [1,1,2,3] 'और' L2 = [1,2,3] ', तो सभी आइटम प्रतिच्छेद करने के लिए दिखाई देंगे।
डोनरोडैडॉन

मुझे पता है कि यह लगभग 10 साल पुराना है, लेकिन पहला समाधान मेरे लिए काम नहीं कर रहा है। मैंने स्ट्रिंग के लिए L2 में संख्याएँ प्रतिस्थापित की हैं, और मुझे निम्नलिखित त्रुटि मिल रही है: TypeError: 'में <string>' के लिए स्ट्रिंग को बाएं ऑपरेंड की आवश्यकता होती है, सूची नहीं
roastbeeef

227

आह, टोबियास तुम मुझे हरा दो। मैं आपके समाधान पर इस मामूली बदलाव के बारे में सोच रहा था:

>>> a = [1,2,3,4]
>>> b = [2,7]
>>> print(any(x in a for x in b))
True

5
मुझे लगता है कि यह एक बहुत पुराना उत्तर है, लेकिन अगर एक सूची बहुत लंबी है और दूसरी छोटी है, तो क्या कोई आदेश है जो तेजी से प्रदर्शन करेगा? (यानी, x in long for x in shortबनाम x in short for x in long)
ल्यूक सपन

11
@ ल्यूकसैप: आप सही हैं। उस ऑर्डर को "मिनट किसी (x, मैक्स, ए, बी, की = लेन) में एक्स के माध्यम से मिनट (ए, बी, की = लेन) के लिए प्राप्त किया जा सकता है।" यह x को लंबे समय तक x के लिए संक्षेप में उपयोग करता है।
नाभिकमान

2
यह सबसे अच्छा उत्तर है क्योंकि यह एक जनरेटर का उपयोग करता है और जैसे ही एक मैच मिलेगा (जैसा कि अन्य लोगों ने कहा है, जैसे ही इस उत्तर पर वापस आ जाएगा!)।
डॉटकॉम

4
@ न्यूक्लियरमैन, देखें: यदि दो सूचियाँ aऔर bएक ही लंबाई हैं, तो अधिकतम और न्यूनतम बाईं सूची में लौट आएंगे, जो any()दोनों तरफ एक ही सूची में कॉल को संचालित करता है । यदि आपको पूरी तरह से लंबाई की जाँच की आवश्यकता है, तो दूसरी कॉल में सूचियों के क्रम को उल्टा करें any(x in max(a, b, key=len) for x in (b, a, key=len)):।
नूह बोगार्ट

3
@NoahBogart आप सही हैं और यह समाधान किसी भी रूप में अच्छा लगता है। मैं भी आप का मतलब है लगता है: any(x in max(a, b, key=len) for x in min(b, a, key=len))(मिनट याद किया)।
न्यूक्लियरमैन

29

शायद थोड़ा और आलसी:

a = [1,2,3,4]
b = [2,7]

print any((True for x in a if x in b))

1
यह लगभग वही है जो मैंने पोस्ट किया था।
बैस्टियन लेओनार्ड

5
@ BastienLéonard ... इसके अलावा यह बहुत तेज़ है क्योंकि यह एक जनरेटर का उपयोग करता है और इस प्रकार anyजल्दी वापस आ सकता है, जबकि आपके संस्करण को पूरी सूची का निर्माण करना चाहिए इससे पहले कि anyआप इसका उपयोग कर सकें। @ user89788 का जवाब थोड़ा बेहतर है क्योंकि डबल कोष्ठक अनावश्यक हैं
एन्ट्रोपिक

17

कोड वास्तव में क्या कहता है इसके बारे में सोचो!

>>> (1 or 2)
1
>>> (2 or 1)
2

शायद इसे समझाना चाहिए। :) पाइथन स्पष्ट रूप से "आलसी या" लागू करता है, जिसे कोई आश्चर्य नहीं होना चाहिए। यह कुछ इस तरह से प्रदर्शन करता है:

def or(x, y):
    if x: return x
    if y: return y
    return False

पहले उदाहरण में, x == 1और y == 2। दूसरे उदाहरण में, यह इसके विपरीत है। इसलिए यह उनके आदेश के आधार पर विभिन्न मूल्यों को लौटाता है।


16
a = {2,3,4}
if {1,2} & a:
    pass

कोड गोल्फ संस्करण। एक सेट का उपयोग करने पर विचार करें यदि यह ऐसा करने के लिए समझ में आता है। मुझे यह एक सूची समझने की तुलना में अधिक पठनीय लगता है।


12

सूची समझ के बिना 1 लाइन।

>>> any(map(lambda each: each in [2,3,4], [1,2]))
True
>>> any(map(lambda each: each in [2,3,4], [1,5]))
False
>>> any(map(lambda each: each in [2,3,4], [2,4]))
True


6

अजगर 3 में हम अनपैक तारांकन का उपयोग शुरू कर सकते हैं। दो सूचियों को दिया:

bool(len({*a} & {*b}))

संपादित करें: अल्केन के सुझाव को शामिल करें


1
@ एंथनी, यह एक सेट को तत्वों से युक्त बनाता है, और दूसरे सेट में तत्वों को समाहित करता है, फिर यह उन सेटों और किसी भी के बीच चौराहे (साझा तत्वों) को ढूंढता है और यदि कोई सत्य है तो ऐसे तत्व हैं। यदि केवल साझा तत्व (s) गलत हैं तो समाधान काम नहीं करेगा (जैसे कि संख्या 0)। किसी भी () की तुलना में लेन () का उपयोग करना बेहतर हो सकता है
1919

1
@ जलानें गुड कॉल
डैनियल ब्रौन

क्यों सेट समारोह का उपयोग करने के लिए नहीं?
एलेक्स78191

5

जब आपको लगता है कि "यह देखने के लिए जांचें कि क्या बी में है", हैश के बारे में सोचें (इस मामले में, सेट करता है)। सबसे तेज़ तरीका उस सूची को हैश करना है जिसे आप जांचना चाहते हैं, और फिर प्रत्येक आइटम की जांच करें।

यही कारण है कि जो रॉबर्ट का जवाब तेजी से है: सेटिंग चौराहे की जांच बहुत तेज है।

जब आपके पास बहुत अधिक डेटा नहीं होता है, तो सेट बनाना समय की बर्बादी हो सकती है। तो, आप सूची का एक सेट बना सकते हैं और प्रत्येक आइटम की जांच कर सकते हैं:

tocheck = [1,2] # items to check
a = [2,3,4] # the list

a = set(a) # convert to set (O(len(a)))
print [i for i in tocheck if i in a] # check items (O(len(tocheck)))

जब आप जिन वस्तुओं को जांचना चाहते हैं, उनकी संख्या छोटी होती है, तो अंतर नगण्य हो सकता है। लेकिन एक बड़ी सूची के खिलाफ संख्या की जाँच करें ...

परीक्षण:

from timeit import timeit

methods = ['''tocheck = [1,2] # items to check
a = [2,3,4] # the list
a = set(a) # convert to set (O(n))
[i for i in tocheck if i in a] # check items (O(m))''',

'''L1 = [2,3,4]
L2 = [1,2]
[i for i in L1 if i in L2]''',

'''S1 = set([2,3,4])
S2 = set([1,2])
S1.intersection(S2)''',

'''a = [1,2]
b = [2,3,4]
any(x in a for x in b)''']

for method in methods:
    print timeit(method, number=10000)

print

methods = ['''tocheck = range(200,300) # items to check
a = range(2, 10000) # the list
a = set(a) # convert to set (O(n))
[i for i in tocheck if i in a] # check items (O(m))''',

'''L1 = range(2, 10000)
L2 = range(200,300)
[i for i in L1 if i in L2]''',

'''S1 = set(range(2, 10000))
S2 = set(range(200,300))
S1.intersection(S2)''',

'''a = range(200,300)
b = range(2, 10000)
any(x in a for x in b)''']

for method in methods:
    print timeit(method, number=1000)

गति:

M1: 0.0170331001282 # make one set
M2: 0.0164539813995 # list comprehension
M3: 0.0286040306091 # set intersection
M4: 0.0305438041687 # any

M1: 0.49850320816 # make one set
M2: 25.2735087872 # list comprehension
M3: 0.466138124466 # set intersection
M4: 0.668627977371 # any

जो विधि लगातार तेज़ होती है वह एक सेट (सूची में) बनाने के लिए होती है, लेकिन बड़े डेटा सेट पर प्रतिच्छेदन सबसे अच्छा काम करता है!


3

कुछ मामलों में (जैसे अद्वितीय सूची तत्व), सेट ऑपरेशन का उपयोग किया जा सकता है।

>>> a=[2,3,4]
>>> set(a) - set([2,3]) != set(a)
True
>>> 

या, set.isdisjoint () का उपयोग करते हुए ,

>>> not set(a).isdisjoint(set([2,3]))
True
>>> not set(a).isdisjoint(set([5,6]))
False
>>> 

2

यह इसे एक लाइन में करेगा।

>>> a=[2,3,4]
>>> b=[1,2]
>>> bool(sum(map(lambda x: x in b, a)))
True

मुझे यहाँ एक ट्रू नहीं मिल रहा है >>> a [2, 3, 4] >>> प्रिंट b [2, 7] >>> कम करें (लंबो x, y: x in b, a) गलत
Deon

हां। आप सही हे। कम () बूलियन मानों को संभालने का तरीका नहीं था जिस तरह से मैंने सोचा था कि यह होगा। संशोधित संस्करण जो मैंने ऊपर लिखा था, हालांकि उस मामले के लिए काम करता है।
क्रिस अपचर्च

2

मैंने अन्य उत्तरों और टिप्पणियों में उल्लिखित कई समाधान एकत्र किए, फिर गति परीक्षण चलाया। not set(a).isdisjoint(b)सबसे तेज़ निकला, परिणाम आने पर यह बहुत धीमा नहीं हुआ False

तीन रनों में से प्रत्येक संभव कॉन्फ़िगरेशन के एक छोटे नमूने का परीक्षण करता है aऔर b। समय माइक्रोसेकंड में हैं।

Any with generator and max
        2.093 1.997 7.879
Any with generator
        0.907 0.692 2.337
Any with list
        1.294 1.452 2.137
True in list
        1.219 1.348 2.148
Set with &
        1.364 1.749 1.412
Set intersection explcit set(b)
        1.424 1.787 1.517
Set intersection implicit set(b)
        0.964 1.298 0.976
Set isdisjoint explicit set(b)
        1.062 1.094 1.241
Set isdisjoint implicit set(b)
        0.622 0.621 0.753

import timeit

def printtimes(t):
    print '{:.3f}'.format(t/10.0),

setup1 = 'a = range(10); b = range(9,15)'
setup2 = 'a = range(10); b = range(10)'
setup3 = 'a = range(10); b = range(10,20)'

print 'Any with generator and max\n\t',
printtimes(timeit.Timer('any(x in max(a,b,key=len) for x in min(b,a,key=len))',setup=setup1).timeit(10000000))
printtimes(timeit.Timer('any(x in max(a,b,key=len) for x in min(b,a,key=len))',setup=setup2).timeit(10000000))
printtimes(timeit.Timer('any(x in max(a,b,key=len) for x in min(b,a,key=len))',setup=setup3).timeit(10000000))
print

print 'Any with generator\n\t',
printtimes(timeit.Timer('any(i in a for i in b)',setup=setup1).timeit(10000000))
printtimes(timeit.Timer('any(i in a for i in b)',setup=setup2).timeit(10000000))
printtimes(timeit.Timer('any(i in a for i in b)',setup=setup3).timeit(10000000))
print

print 'Any with list\n\t',
printtimes(timeit.Timer('any([i in a for i in b])',setup=setup1).timeit(10000000))
printtimes(timeit.Timer('any([i in a for i in b])',setup=setup2).timeit(10000000))
printtimes(timeit.Timer('any([i in a for i in b])',setup=setup3).timeit(10000000))
print

print 'True in list\n\t',
printtimes(timeit.Timer('True in [i in a for i in b]',setup=setup1).timeit(10000000))
printtimes(timeit.Timer('True in [i in a for i in b]',setup=setup2).timeit(10000000))
printtimes(timeit.Timer('True in [i in a for i in b]',setup=setup3).timeit(10000000))
print

print 'Set with &\n\t',
printtimes(timeit.Timer('bool(set(a) & set(b))',setup=setup1).timeit(10000000))
printtimes(timeit.Timer('bool(set(a) & set(b))',setup=setup2).timeit(10000000))
printtimes(timeit.Timer('bool(set(a) & set(b))',setup=setup3).timeit(10000000))
print

print 'Set intersection explcit set(b)\n\t',
printtimes(timeit.Timer('bool(set(a).intersection(set(b)))',setup=setup1).timeit(10000000))
printtimes(timeit.Timer('bool(set(a).intersection(set(b)))',setup=setup2).timeit(10000000))
printtimes(timeit.Timer('bool(set(a).intersection(set(b)))',setup=setup3).timeit(10000000))
print

print 'Set intersection implicit set(b)\n\t',
printtimes(timeit.Timer('bool(set(a).intersection(b))',setup=setup1).timeit(10000000))
printtimes(timeit.Timer('bool(set(a).intersection(b))',setup=setup2).timeit(10000000))
printtimes(timeit.Timer('bool(set(a).intersection(b))',setup=setup3).timeit(10000000))
print

print 'Set isdisjoint explicit set(b)\n\t',
printtimes(timeit.Timer('not set(a).isdisjoint(set(b))',setup=setup1).timeit(10000000))
printtimes(timeit.Timer('not set(a).isdisjoint(set(b))',setup=setup2).timeit(10000000))
printtimes(timeit.Timer('not set(a).isdisjoint(set(b))',setup=setup3).timeit(10000000))
print

print 'Set isdisjoint implicit set(b)\n\t',
printtimes(timeit.Timer('not set(a).isdisjoint(b)',setup=setup1).timeit(10000000))
printtimes(timeit.Timer('not set(a).isdisjoint(b)',setup=setup1).timeit(10000000))
printtimes(timeit.Timer('not set(a).isdisjoint(b)',setup=setup3).timeit(10000000))
print

0

मेरा कहना है कि मेरी स्थिति वह नहीं हो सकती जो आप खोज रहे हैं, लेकिन यह आपकी सोच का विकल्प प्रदान कर सकता है।

मैंने दोनों सेट () और किसी भी () विधि की कोशिश की है, लेकिन अभी भी गति के साथ समस्याएं हैं। तो मुझे याद आया कि रेमंड हेटिंगर ने कहा था कि अजगर में सब कुछ एक शब्दकोष है और जब भी आप कर सकते हैं, तानाशाही का उपयोग करें। तो यही मैंने कोशिश की।

मैंने नकारात्मक परिणामों को इंगित करने के लिए int के साथ एक डिफ़ॉल्ट का उपयोग किया और पहली सूची में आइटम का उपयोग दूसरी सूची की कुंजी के रूप में किया (डिफ़ॉल्ट रूप में परिवर्तित)। चूँकि आपको डिक्टेट के साथ तुरंत लुकअप है, आप तुरंत जानते हैं कि क्या डिफॉल्ट में वह आइटम मौजूद है। मुझे पता है कि आपको हमेशा अपनी दूसरी सूची के लिए डेटा संरचना बदलने की ज़रूरत नहीं है, लेकिन यदि आप शुरू से सक्षम हैं, तो यह बहुत तेज़ है। आपको सूची 2 (बड़ी सूची) को एक डिफ़ॉल्ट में बदलना पड़ सकता है, जहाँ कुंजी वह संभावित मान है जिसे आप छोटी सूची से जाँचना चाहते हैं, और मान 1 (हिट) या 0 (कोई हिट, डिफ़ॉल्ट) नहीं है।

from collections import defaultdict
already_indexed = defaultdict(int)

def check_exist(small_list, default_list):
    for item in small_list:
        if default_list[item] == 1:
            return True
    return False

if check_exist(small_list, already_indexed):
    continue
else:
    for x in small_list:
        already_indexed[x] = 1

-4

सरल।

_new_list = []
for item in a:
    if item in b:
        _new_list.append(item)
    else:
        pass

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