পাইথন এমন একটি তালিকায় এমন উপাদান আবিষ্কার করে যা অন্যটিতে নেই [নকল]


135

একটি তালিকায় পাওয়া গেলেও অন্যটিতে নয় নির্দিষ্ট উপাদানের একটি নতুন তালিকা তৈরি করতে আমার দুটি তালিকার তুলনা করতে হবে। উদাহরণ স্বরূপ:

main_list=[]
list_1=["a", "b", "c", "d", "e"]
list_2=["a", "f", "c", "m"] 

আমি তালিকা_1 এর মধ্য দিয়ে লুপ করতে চাইছি এবং তালিকা_এর সমস্ত উপাদান যা তালিকায় পাওয়া যায় নি প্রধান তালিকাতে যোগ করতে চাই _1

ফলাফলটি হওয়া উচিত:

main_list=["f", "m"]

অজগর দিয়ে কীভাবে করব?


2
আপনি কি list_2সেই উপাদানগুলির সন্ধান করছেন যা কোথাও উপস্থিত নেই list_1বা উপাদানগুলি list_2একই সূচকটিতে উপস্থিত নেই list_1?
প্যাট্রিক হাহ

উত্তর:


95

টিএল; ডিআর:
সমাধান (1)

import numpy as np
main_list = np.setdiff1d(list_2,list_1)
# yields the elements in `list_2` that are NOT in `list_1`

সমাধান (2) আপনি একটি বাছাই তালিকা চান

def setdiff_sorted(array1,array2,assume_unique=False):
    ans = np.setdiff1d(array1,array2,assume_unique).tolist()
    if assume_unique:
        return sorted(ans)
    return ans
main_list = setdiff_sorted(list_2,list_1)




ব্যাখ্যা:
(1) আপনি NumPy এর ব্যবহার করতে পারেন setdiff1d( array1, array2, assume_unique= False)।

assume_uniqueব্যবহারকারীদের জিজ্ঞাসা করুন যদি অ্যারেগুলি আগেই অনন্য হয়।
যদি False, তবে অনন্য উপাদানগুলি প্রথমে নির্ধারিত হয়।
যদি True, ফাংশনটি ধরে নিবে যে উপাদানগুলি ইতিমধ্যে অনন্য এবং ফাংশনটি অনন্য উপাদানগুলি নির্ধারণ করতে এড়িয়ে যাবে।

এই উৎপাদনের অনন্য মান array1যে হয় নাarray2assume_uniqueহয় Falseডিফল্টরূপে।

যদি আপনি অনন্য উপাদানগুলির সাথে চিন্তিত হন ( চিনি 84 এর প্রতিক্রিয়ার ভিত্তিতে ), তবে কেবল (যেখানে assume_unique=False=> ডিফল্ট মান) ব্যবহার করুন:

import numpy as np
list_1 = ["a", "b", "c", "d", "e"]
list_2 = ["a", "f", "c", "m"] 
main_list = np.setdiff1d(list_2,list_1)
# yields the elements in `list_2` that are NOT in `list_1`


(২) যারা উত্তরগুলি বাছাই করতে চান তাদের জন্য, আমি একটি কাস্টম ফাংশন করেছি:

import numpy as np
def setdiff_sorted(array1,array2,assume_unique=False):
    ans = np.setdiff1d(array1,array2,assume_unique).tolist()
    if assume_unique:
        return sorted(ans)
    return ans

উত্তর পেতে, চালান:

main_list = setdiff_sorted(list_2,list_1)

সাইড নোট:
(ক) সমাধান 2 (কাস্টম ফাংশন setdiff_sorted) একটি তালিকা দেয় ( সমাধান 1 এর অ্যারের তুলনায় )।

(খ) আপনি যদি উপাদানগুলি অনন্য কিনা তা নিশ্চিত না হন তবে কেবলমাত্র setdiff1dএ এবং বি উভয় সমাধানে নুমপি'র ডিফল্ট সেটিংটি ব্যবহার করুন কোনও জটিলতার উদাহরণ কী হতে পারে? নোট দেখুন (গ)।

(গ) দুটি তালিকার একটিরও অনন্য না হলে বিষয়গুলি পৃথক হবে ।
বলুন list_2অনন্য নয়: list2 = ["a", "f", "c", "m", "m"]list1হিসাবে রাখুন : ফলনের list_1 = ["a", "b", "c", "d", "e"]
ডিফল্ট মান নির্ধারণ (উভয় সমাধানে)। যাইহোক, যদি আপনি সেট করেন তবে উভয় সমাধানই দেয় । কেন? এটি ব্যবহারকারীর মনে হয়েছে যে উপাদানগুলি অনন্য। সুতরাং, এটি রাখা ভালassume_unique["f", "m"]assume_unique=True["f", "m", "m"]assume_uniqueএর ডিফল্ট মান। মনে রাখবেন যে উভয় উত্তর বাছাই করা হয়।


যদি আপনার তালিকাগুলি ইতিমধ্যে অর্ডার করা হয় তবে এটি একটি আদেশযুক্ত তালিকাও ফিরিয়ে দেবে। সেটগুলিতে রূপান্তর করার এবং তারপরে পার্থক্য পাওয়ার নেটিভ সমাধান (নীচে দেখানো সমাধানগুলি) একটি নিরবচ্ছিন্ন তালিকা দেয় যা আপনার ফলাফলগুলিকে চাক্ষুষরূপে পরীক্ষা করা আরও কঠিন করে তুলতে পারে।
ডাবলডাউন

1
হাই, @ ডাবলডাউন! আপনার উদ্বেগ সম্পাদিত পোস্টে সম্বোধন করা হয়েছে। আশাকরি এটা সাহায্য করবে!
jcoderepo

182

আপনি সেট ব্যবহার করতে পারেন:

main_list = list(set(list_2) - set(list_1))

আউটপুট:

>>> list_1=["a", "b", "c", "d", "e"]
>>> list_2=["a", "f", "c", "m"]
>>> set(list_2) - set(list_1)
set(['m', 'f'])
>>> list(set(list_2) - set(list_1))
['m', 'f']

@ জোনক্লিমেন্টস'র মন্তব্যে, এখানে একটি জোয়ার সংস্করণ দেওয়া হয়েছে:

>>> list_1=["a", "b", "c", "d", "e"]
>>> list_2=["a", "f", "c", "m"]
>>> list(set(list_2).difference(list_1))
['m', 'f']

2
এটি কেবলমাত্র যদি কেবলমাত্র uniqueউপাদানগুলির বিষয়ে চিন্তা করি তবে আমাদের পক্ষে যদি একাধিকটি থাকে তবে এটি কী m'sতা গ্রহণ করবে না তা ভাল।
চিনি 84

সেটা সত্য. আমি ধরে নিয়েছি পোস্টারটি অনন্য উপাদানগুলির সন্ধান করছে। আমি মনে করি এটি "নির্দিষ্ট" দ্বারা তিনি কী বোঝাতে চান তার উপর নির্ভর করে।
nrlakin

প্রকৃতপক্ষে PS আমি আপনার উত্তরটি বিশেষত একটি অস্পষ্ট মূল প্রশ্নের জন্য ভোট দিয়েছি না।
চিনি 84

13
আপনি এটি লিখতে পারেন list(set(list_2).difference(list_1))যা স্পষ্ট setরূপান্তর এড়ায় ...
জন ক্লিমেটস

কোন চিন্তা করো না! ফর্ম্যাটিং সহায়তার জন্য @ লিফকে ধন্যবাদ।
nrlakin

59

আপনার যখন স্থানীয় পদ্ধতি উপলব্ধ থাকে তখন উপরের ব্যাখ্যাগুলি এত জটিল কেন তা নিশ্চিত নন:

main_list = list(set(list_2)-set(list_1))

6
অর্ডার সংরক্ষণের কারণ হতে পারে
কিথ

57

এই জন্য একটি তালিকা বোধগম্য ব্যবহার করুন :

main_list = [item for item in list_2 if item not in list_1]

আউটপুট:

>>> list_1 = ["a", "b", "c", "d", "e"]
>>> list_2 = ["a", "f", "c", "m"] 
>>> 
>>> main_list = [item for item in list_2 if item not in list_1]
>>> main_list
['f', 'm']

সম্পাদনা:

নীচের মন্তব্যে উল্লিখিত মত, বড় তালিকাগুলি সহ, উপরোক্ত আদর্শ সমাধান নয়। যখন যে ক্ষেত্রে, একটি ভাল বিকল্প রূপান্তর হবে list_1একটি থেকে setপ্রথম:

set_1 = set(list_1)  # this reduces the lookup time from O(n) to O(1)
main_list = [item for item in list_2 if item not in set_1]

3
দ্রষ্টব্য: বৃহত্তর জন্য list_1, আপনি একটি set/ হিসাবে প্রাক রূপান্তর করতে চান frozenset, উদাহরণস্বরূপ set_1 = frozenset(list_1), প্রতি আইটেম main_list = [item for item in list_2 if item not in set_1]থেকে চেক সময় হ্রাস O(n)(মোটামুটি) O(1)
শ্যাডোর্যাঞ্জার

@ ইত্তানানি দয়া করে সাবধান হোন যদি আপনি ইত্তানানির পোস্টের মতো সমাধানটি চেষ্টা করেন। আমি ইটানানির সমাধানটি যেমন চেষ্টা করেছি এবং এটি বৃহত্তর তালিকার জন্য খুব ধীর। শেডর্যাঞ্জারের পরামর্শ অন্তর্ভুক্ত করার জন্য আপনি উত্তরটি আপডেট করতে পারেন?
ডাবলডাউন

স্ট্রিংয়ের পরিবর্তে সূচি পাওয়া কি সম্ভব?
জ্যারেবিয়ার

@ জ্যারেবার আপনি এটির enumerate()জন্য ব্যবহার করতে পারেন :[index for (index, item) in enumerate(list_2) if item not in list_1]
এটানানি

@ এটানানির অনেক ধন্যবাদ আপনাকে !! আমি যে asap বাস্তবায়ন করব, আমি এটি সম্পন্ন করেছি। তবে আপনার কোডটি দেখতে অনেক পরিষ্কার।
জ্যারেবিয়ার

5

আপনি যদি ওয়ান-লাইনারের সমাধান (আমদানি উপেক্ষা করে) চান যা কেবল O(max(n, m))দৈর্ঘ্যের ইনপুটগুলির জন্য কাজ প্রয়োজন nএবং কাজ mনয় O(n * m), আপনি মডিউলটি দিয়ে এটিitertools করতে পারেন :

from itertools import filterfalse

main_list = list(filterfalse(set(list_1).__contains__, list_2))

এটি নির্মাণে কলব্যাক ফাংশন গ্রহণকারী ক্রিয়ামূলক ফাংশনগুলির সুবিধা গ্রহণ করে, এটি একবার কলব্যাক তৈরি করতে দেয় এবং এটি কোথাও সংরক্ষণ করার প্রয়োজন ছাড়াই প্রতিটি উপাদানগুলির জন্য এটি পুনরায় ব্যবহার করতে দেয় (কারণ filterfalseএটি অভ্যন্তরীণভাবে সঞ্চয় করে); তালিকা উপলব্ধি এবং জেনারেটরের এক্সপ্রেশনগুলি এটি করতে পারে তবে এটি কুৎসিত †

এটি একক লাইনে একই ফলাফল পায়:

main_list = [x for x in list_2 if x not in list_1]

এর গতি সহ:

set_1 = set(list_1)
main_list = [x for x in list_2 if x not in set_1]

অবশ্যই, তুলনাগুলি যদি অবস্থানগত হওয়ার উদ্দেশ্যে হয়, তাই:

list_1 = [1, 2, 3]
list_2 = [2, 3, 4]

উত্পাদন করা উচিত:

main_list = [2, 3, 4]

(কারণ list_2একই সূচকের সাথে মানটির মিল রয়েছে list_1), আপনার অবশ্যই প্যাট্রিকের জবাবের সাথে যেতে হবে , এতে কোনও অস্থায়ী listএস বা setগুলি জড়িত না (এমনকি setমোটামুটিভাবে থাকা সত্ত্বেও O(1), সাধারণ সাম্যতার পরীক্ষার চেয়ে চেক প্রতি তাদের উচ্চতর "ধ্রুবক" ফ্যাক্টর রয়েছে) ) এবং O(min(n, m))কাজের সাথে জড়িত , অন্য কোনও উত্তরের চেয়ে কম, এবং যদি আপনার সমস্যাটি অবস্থান সংবেদনশীল হয় তবে একমাত্র সঠিক সমাধান যখন ম্যাচিং উপাদানগুলি মিল না পাওয়া অফসেটগুলিতে উপস্থিত হয়।

†: ওয়ান-লাইনার হিসাবে তালিকা বোধের সাথে একই জিনিসটি করার উপায় হ'ল নেস্টেড লুপিংকে "বাহ্যতমতম" লুপে মান (গুলি) তৈরি করতে এবং ক্যাশে মান (গুলি) ব্যবহার করা, যেমন:

main_list = [x for set_1 in (set(list_1),) for x in list_2 if x not in set_1]

যা পাইথন 3-তে সামান্য পারফরম্যান্স সুবিধা দেয় (কারণ এখন set_1প্রতিটি চেকের জন্য নেস্টেড স্কোপ থেকে সন্ধান করার পরিবর্তে স্থানীয়ভাবে বোঝার কোডে স্কোপ করা হয়; পাইথন 2 তে কিছু যায় আসে না, কারণ পাইথন 2 ক্লোজার ব্যবহার করে না বোধগম্য তালিকাভুক্ত করুন; তারা একই স্কোপটিতে তারা ব্যবহার করছেন)।


4
main_list=[]
list_1=["a", "b", "c", "d", "e"]
list_2=["a", "f", "c", "m"]

for i in list_2:
    if i not in list_1:
        main_list.append(i)

print(main_list)

আউটপুট:

['f', 'm']

ভালো লেগেছে সমতুল্য তালিকা ধী ভিত্তিক সমাধান , এই ধীর হতে হবে list_1বড়, এবং list_2অ তুচ্ছ আকারের হয়, কারণ এটি জড়িত len(list_2) O(n)স্ক্যান list_1, এটা উপার্জন O(n * m)(যেখানে nএবং mএর লেন্থ হয় list_2এবং list_1যথাক্রমে)। আপনি যদি list_1কোনও set/ frozensetআপ ফ্রন্টে রূপান্তর করেন তবে এতে অন্তর্ভুক্ত চেকগুলি করা যেতে পারে O(1), মোট O(n)দৈর্ঘ্যের উপর list_2(টেকনিক্যালি O(max(n, m)), যেহেতু আপনি O(m)তৈরির কাজ করেন set)।
শ্যাডোর্যাঞ্জার

1

আমি zipতালিকাগুলি এক সাথে উপাদানগুলির সাথে উপাদানগুলির সাথে তুলনা করতে চাই।

main_list = [b for a, b in zip(list1, list2) if a!= b]

যদি ওপি উপাদানটির সাথে উপাদানটির তুলনা করতে চায় (এটি অস্পষ্ট, উদাহরণটি যে কোনও উপায়ে যেতে পারে), এটি অন্যান্য উত্তরগুলির তুলনায় অনেক বেশি দক্ষ, কারণ এটি উভয়টিরই listএকক নতুন listনির্মাণের সাথে একটি সস্তা সস্তা পাস , কোনও অতিরিক্ত অস্থায়ী নয় কোনও দামী সংবরণ চেক, ইত্যাদি
ShadowRanger

1
@ শ্যাডোএ্যাঞ্জার এটি কেবলমাত্র উপাদান-ভিত্তিক পার্থক্যের জন্য কাজ করবে যা একটি মূল বিষয়
ফোর্ড প্রিফেক্ট

@ ফোর্ডপ্রেফেক্ট: হ্যাঁ আমার নিজের উত্তরটিতে অবস্থান-স্বতন্ত্র পার্থক্য রয়েছে।
শ্যাডোএ্যাঞ্জার

1

আমি দুটি পদ্ধতি ব্যবহার করেছি এবং আমি একটি পদ্ধতি অন্যটির তুলনায় দরকারী বলে মনে করেছি। আমার উত্তর এখানে:

আমার ইনপুট ডেটা:

crkmod_mpp = ['M13','M18','M19','M24']
testmod_mpp = ['M13','M14','M15','M16','M17','M18','M19','M20','M21','M22','M23','M24']

পদ্ধতি 1: np.setdiff1dআমি অন্যদের চেয়ে এই পদ্ধতির পছন্দ করি কারণ এটি অবস্থানটি সংরক্ষণ করে

test= list(np.setdiff1d(testmod_mpp,crkmod_mpp))
print(test)
['M15', 'M16', 'M22', 'M23', 'M20', 'M14', 'M17', 'M21']

পদ্ধতি 2: যদিও এটি মেথড 1-এর মতো একই উত্তর দেয় তবে ক্রমকে বিঘ্নিত করে

test = list(set(testmod_mpp).difference(set(crkmod_mpp)))
print(test)
['POA23', 'POA15', 'POA17', 'POA16', 'POA22', 'POA18', 'POA24', 'POA21']

পদ্ধতি 1 np.setdiff1dআমার প্রয়োজনীয়তা পুরোপুরি পূরণ করে। তথ্যের জন্য এই উত্তর।


0

ঘটনার সংখ্যাটি যদি বিবেচনায় নেওয়া উচিত তবে আপনাকে সম্ভবত এর মতো কিছু ব্যবহার করতে হবে collections.Counter:

list_1=["a", "b", "c", "d", "e"]
list_2=["a", "f", "c", "m"] 
from collections import Counter
cnt1 = Counter(list_1)
cnt2 = Counter(list_2)
final = [key for key, counts in cnt2.items() if cnt1.get(key, 0) != counts]

>>> final
['f', 'm']

প্রতিশ্রুতিবদ্ধ হিসাবে এটি "পার্থক্য" হিসাবে বিভিন্ন সংখ্যক উপস্থিতি পরিচালনা করতে পারে:

list_1=["a", "b", "c", "d", "e", 'a']
cnt1 = Counter(list_1)
cnt2 = Counter(list_2)
final = [key for key, counts in cnt2.items() if cnt1.get(key, 0) != counts]

>>> final
['a', 'f', 'm']

-1

Ser1 থেকে Ser2 এ উপস্থিত আইটেমগুলি সরান।

ইনপুট

ser1 = pd.Series ([1, 2, 3, 4, 5]) ser2 = pd.Series ([4, 5, 6, 7, 8])

সমাধান

ser1 [~ ser1.isin (ser2)]


স্ট্যাক ওভারফ্লোতে আপনাকে স্বাগতম। এই প্রশ্নের অন্য আটটি প্রতিক্রিয়া রয়েছে যার একটির মূল পোস্টার গ্রহণ করেছে। আপনার উত্তর ইতিমধ্যে উপস্থাপিত হয়েছে কিভাবে তার উন্নতি দয়া করে বর্ণনা করুন।
chb
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.