নিম্নলিখিত আইটেমগুলির মধ্যে একটি তালিকায় রয়েছে কিনা তা কীভাবে পরীক্ষা করবেন?


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
ছেদ করার ধারণাটি আমাকে এই ধারণা দিয়েছে। রিটার্ন লেন (সেট (ক)। আন্তঃশক্তি (সেট (খ)))
দেওন

13
এফডাব্লুআইডাব্লু - আমি একটি গতির তুলনা করেছি এবং এখানে প্রদত্ত প্রথম সমাধানটি খুব দ্রুত উপোস করা হয়েছিল।
jackiekazil

2
জেনারেটর ব্যবহার করে @ ব্যবহারকারী89788 এর উত্তরটি আবার অনেক দ্রুত, কারণ anyকোনও Trueমূল্য খুঁজে পাওয়ার সাথে সাথে তাড়াতাড়ি ফিরে আসতে পারে
অ্যান্ট্রোপিক

তালিকায় নকল থাকলে দ্বিতীয় / সেট সমাধান কাজ করবে না (যেমন সেটগুলিতে কেবল প্রতিটি আইটেমের মধ্যে একটি থাকে)। যদি `এল 1 = [1,1,2,3] 'এবং' এল 2 = [1,2,3] 'হয়, সমস্ত আইটেম ছেদ করতে দেখা যাবে।
ডোনারডাডন

আমি জানি এটি প্রায় 10 বছর পুরানো, তবে প্রথম সমাধানটি আমার পক্ষে কাজ করে না বলে মনে হয়। আমি স্ট্রিংয়ের জন্য সংখ্যাগুলিকে এল 2 তে প্রতিস্থাপন করেছি এবং আমি নিম্নলিখিত ত্রুটিটি পেয়েছি: টাইপ এয়ার: 'স্ট্রিং>' তে স্ট্রিং বাম অপারেণ্ডের প্রয়োজন, তালিকা নয়
পেয়েছি: টাইপ অপারেণ্ডের রোস্টবিইফ

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 (ক, খ, কী = লেন)) মুদ্রণের মাধ্যমে পাওয়া যাবে"। এটি সংক্ষেপে এক্স দীর্ঘ জন্য এক্স ব্যবহার করে।
নিউক্লিয়ারম্যান

2
এটি সেরা উত্তর কারণ এটি কোনও জেনারেটর ব্যবহার করে এবং কোনও ম্যাচ পাওয়া মাত্রই ফিরে আসবে (অন্যরা যেমন বলেছে, কেবল এই উত্তরে নয়!)।
ডটকমলি

4
@ নিউক্লিয়ারম্যান, নজর রাখুন: দুটি তালিকা aএবং bযদি একই দৈর্ঘ্য হয় তবে সর্বাধিক এবং মিনিট বাম-সর্বাধিক তালিকাটি ফিরিয়ে দেবে, যা any()কলটি উভয় পক্ষের একই তালিকার উপরে পরিচালিত করে। আপনি একেবারে দৈর্ঘ্যের জন্য চেক প্রয়োজন হয়, দ্বিতীয় কলে তালিকার ক্রম বিপরীত: any(x in max(a, b, key=len) for x in (b, a, key=len))
নোহ বোগার্ট

3
@ নোহবোগার্ট আপনি সঠিক এবং এই সমাধানটি যতটা ভাল বলে মনে হচ্ছে। আমিও ধরে নিয়েছি আপনি বোঝাতে চেয়েছিলেন: 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
@ বাসটিএলোনার্ড ... এটির চেয়ে অনেক দ্রুত কারণ এটি কোনও জেনারেটর ব্যবহার করে এবং anyতাড়াতাড়ি ফিরে আসতে পারে, তবে আপনার সংস্করণটি anyব্যবহারের আগে বোঝার থেকে পুরো তালিকাটি তৈরি করতে হবে। @ ব্যবহারকারী89788 এর উত্তরটি কিছুটা ভাল কারণ ডাবল প্রথম বন্ধনী অপ্রয়োজনীয়
অ্যান্ট্রপিক

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
@ অ্যান্টনি, এটি একটিতে উপাদান রয়েছে এমন একটি সেট তৈরি করে, এবং বিতে উপাদানগুলি সহ আরও একটি সেট তৈরি করে, তারপরে সেগুলি সেটগুলির মধ্যে ছেদ (ভাগ করা উপাদানগুলি) খুঁজে পায় এবং কোনও () সত্যবাদী হয় যদি এমন কোনও উপাদান থাকে তবে সত্যটি ফিরে আসে। সমাধানটি কাজ করবে না যদি কেবলমাত্র ভাগ করা উপাদান (গুলি) মিথ্যা হয় (যেমন 0 নম্বর)। এটা ভাল lên ব্যবহার করবেন () চেয়ে কোনো () হতে পারে
alkanen

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.isdisjPoint () ব্যবহার করে ,

>>> 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

আমি এখানে সত্যই পাচ্ছি না >>> একটি [2, 3, 4] >>> বি মুদ্রণ করুন [2, 7] >>> হ্রাস করুন (ল্যাম্বদা এক্স, ওয়াই: এক্স ইন বি, ক) মিথ্যা
দেওন

হাঁ। তুমি ঠিক বলছো. হ্রাস () বুলিয়ান মানগুলি যেভাবে ভেবেছিল তা হ্যান্ডেল করে নি। আমি উপরে যে সংশোধিত সংস্করণটি লিখেছি তা সে ক্ষেত্রে কাজ করে।
ক্রিস আপচর্চ

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 সহ একটি ডিফল্টডিক্ট ব্যবহার করেছি এবং দ্বিতীয় তালিকার কী হিসাবে প্রথম তালিকায় আইটেমটি ব্যবহার করেছি (ডিফল্টডিক্টে রূপান্তরিত)। আপনার ডিকের সাথে তাত্ক্ষণিক নজর রয়েছে, তাই আপনি অবিলম্বে জানবেন যে আইটেমটি ডিফল্টরূপে বিদ্যমান whether আমি জানি আপনি সর্বদা আপনার দ্বিতীয় তালিকার জন্য ডেটা কাঠামো পরিবর্তন করতে পাবেন না, তবে আপনি যদি প্রথম থেকেই সক্ষম হন তবে এটি আরও দ্রুত। আপনাকে তালিকা 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
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.