এক তালিকায় দেখা যায় এমন সমস্ত উপাদান অপর থেকে সরান


365

ধরা যাক আমার দুটি তালিকা রয়েছে l1এবং l2। আমি সম্পাদন করতে চাই l1 - l2, যা সমস্ত উপাদানগুলিকে সরিয়ে দেয় l1না l2

আমি এটি করার জন্য একটি নিষ্পাপ লুপ পদ্ধতির কথা ভাবতে পারি, তবে এটি সত্যিই অকার্যকর হতে চলেছে। এটি করার একটি অজগর এবং দক্ষ উপায় কি?

উদাহরণস্বরূপ, যদি আমি আছে l1 = [1,2,6,8] and l2 = [2,3,5,8], l1 - l2ফিরে যাওয়া উচিত[1,6]


12
কেবলমাত্র একটি টিপ: পিইপি 8 বলেছে যে ছোট হাতের এল "এল" ব্যবহার করা উচিত নয় কারণ এটি দেখতে অনেকটা 1. এর মতো লাগে
spelchekr

2
আমি রাজী. লোকেরা কেন এগারো এবং বারোটি ব্যবহার করে চলেছে তা অবাক করে আমি এই পুরো প্রশ্নটি এবং উত্তরগুলি পড়েছি। আমি যখনই @ স্পেলচেকারের মন্তব্য পড়ি তখনই তা উপলব্ধি হয়ে যায়।
21:15


@JimG। ডেটাফ্রেম এবং তালিকা একই জিনিস নয়।
কার্যকলাপ হ্রাস

উত্তর:


491

পাইথনের একটি ভাষা বৈশিষ্ট্য রয়েছে যার নাম তালিকা রয়েছে যা এই ধরণের জিনিসটিকে অত্যন্ত সহজ করে তোলার জন্য পুরোপুরি উপযুক্ত। নিম্নলিখিত বিবৃতিটি আপনি যা চান ঠিক তা করে এবং ফলাফলটি সংরক্ষণ করে l3:

l3 = [x for x in l1 if x not in l2]

l3উপস্থিত থাকবে [1, 6]


8
খুব অজগর; আমি এটা পছন্দ করি! এটা কতটা দক্ষ?
পরশু

2
আমি বেশ দক্ষ বিশ্বাস করি এবং আপনি কী অর্জন করতে চাইছেন তা সম্পর্কে অত্যন্ত পঠনযোগ্য এবং স্পষ্ট হওয়ার উপকার রয়েছে। : আমি আপনাকে দক্ষতা সংক্রান্ত আকর্ষণীয় হতে পারে একটি ব্লগ পোস্টে জুড়ে এসেছিল blog.cdleary.com/2010/04/efficiency-of-list-comprehensions
ডোনাট

6
@ ফ্যানডম: তালিকা অনুধাবন নিজেই বেশ দক্ষ (যদিও জেনারেটর বোধগম্যতা স্মৃতিতে উপাদানগুলি নকল না করে আরও দক্ষ হতে পারে), তবে inঅপারেটর কোনও তালিকার পক্ষে তেমন দক্ষ নয়। inএকটি তালিকায় ও (এন) রয়েছে, তবে inএকটি সেটে ও (1) রয়েছে। যাইহোক, আপনি হাজার হাজার উপাদান বা তারও বেশি কাছে না আসা পর্যন্ত আপনি পার্থক্যটি লক্ষ্য করবেন না।
ড্যানিয়েল প্রাইডেন

1
l3 = [x for x in l1 if x not in set(l2)]? আমি নিশ্চিত যে set(l2)একাধিকবার ফোন করা হবে কিনা ।
ড্যানোসরে

5
আপনি ঠিক সেট l2s = set(l2)এবং তারপর বলতে পারে l3 = [x for x in l1 if x not in l2s]। সামান্য সহজ।
spelchekr

149

একটি উপায় সেট ব্যবহার করা হয়:

>>> set([1,2,6,8]) - set([2,3,5,8])
set([1, 6])

58
এটি এর থেকে l1সদৃশও সরিয়ে ফেলবে , যা অনাকাঙ্খিত পার্শ্ব প্রতিক্রিয়া হতে পারে।
kindall

37
.. এবং উপাদান ক্রম হারাতে (যদি আদেশ গুরুত্বপূর্ণ)।
ড্যানোসরে

3
আমি শুধু যোগ করার জন্য যে, আমি বনাম গৃহীত উত্তর এই সময় শেষ হয়েছে এবং এটি 3 সম্পর্কে একটি গুণক দ্বারা আরো performant ছিল চাই: timeit.timeit('a = [1,2,3,4]; b = [1,3]; c = [i for i in a if a not in b]', number=100000) -> 0.12061533199999985 timeit.timeit('a = {1,2,3,4}; b = {1,3}; c = a - b', number=100000) -> 0.04106225999998969। সুতরাং যদি পারফরম্যান্স একটি তাৎপর্যপূর্ণ বিষয় হয় তবে এই উত্তরটি আরও উপযুক্ত হতে পারে (এবং যদি আপনি নকলগুলি বা অর্ডার সম্পর্কেও চিন্তা করেন না)
wfgeo

37

বিকল্প হিসাবে, আপনি পছন্দসই ফলাফল পেতে ল্যাম্বডা এক্সপ্রেশন দিয়েও ব্যবহারfilter করতে পারেন । উদাহরণ স্বরূপ:

>>> l1 = [1,2,6,8]
>>> l2 = set([2,3,5,8])

#     v  `filter` returns the a iterator object. Here I'm type-casting 
#     v  it to `list` in order to display the resultant value
>>> list(filter(lambda x: x not in l2, l1))
[1, 6]

পারফরম্যান্স তুলনা

আমি এখানে উল্লিখিত সমস্ত উত্তরগুলির কার্যকারিতা তুলনা করছি। যেমনটি প্রত্যাশা করা হয়েছিল, আরক্কুর set ভিত্তিক অপারেশনটি দ্রুততম।

পিএস: set অর্ডার বজায় রাখে না এবং তালিকা থেকে সদৃশ উপাদানগুলি সরিয়ে দেয়। সুতরাং, আপনার যদি এর কোনওটির প্রয়োজন হয় তবে সেট পার্থক্যটি ব্যবহার করবেন না ।


32

ডোনাটের উত্তর এবং অন্যান্য উত্তরগুলি এখানে প্রসারিত করে, আপনি তালিকা বোধের পরিবর্তে জেনারেটর বোধগম্যতা ব্যবহার করে এবং একটি setডাটা স্ট্রাকচার ব্যবহার করে (যেহেতু inঅপারেটর একটি তালিকায় ও (এন) তবে ও (1) ব্যবহার করে আরও ভাল ফলাফল পেতে পারেন একটি সেট উপর)।

সুতরাং এখানে একটি ফাংশন যা আপনার পক্ষে কাজ করবে:

def filter_list(full_list, excludes):
    s = set(excludes)
    return (x for x in full_list if x not in s)

ফলাফলটি এমন একটি পুনরাবৃত্ত হবে যা অলসভাবে ফিল্টারকৃত তালিকা আনবে। আপনার যদি সত্যিকারের তালিকা সামগ্রীর প্রয়োজন হয় (উদাহরণস্বরূপ যদি আপনাকে len()ফলাফলটি করার প্রয়োজন হয় ) তবে আপনি সহজেই এর মতো একটি তালিকা তৈরি করতে পারেন:

filtered_list = list(filter_list(full_list, excludes))

29

পাইথন সেট প্রকারটি ব্যবহার করুন। এটি হবে সর্বাধিক পাইথোনিক। :)

এছাড়াও, যেহেতু এটি নেটিভ, তাই এটিও সবচেয়ে অনুকূলিত পদ্ধতি হওয়া উচিত।

দেখা:

http://docs.python.org/library/stdtypes.html#set

http://docs.python.org/library/sets.htm (পুরানো অজগর জন্য)

# Using Python 2.7 set literal format.
# Otherwise, use: l1 = set([1,2,6,8])
#
l1 = {1,2,6,8}
l2 = {2,3,5,8}
l3 = l1 - l2

5
সেটগুলি ব্যবহার করার সময় এটি লক্ষ্য করা উচিত যে আউটপুট অর্ডার করা হয়েছে, অর্থাৎ {1,3,2} হয়ে যায় {1,2,3 {এবং {"এ", "সি", "বি"} {"এ" হয়ে যায়, "বি", "সি"} এবং আপনি এটি পেতে চাইবেন না।
পাবলো রেয়েস

2
তালিকায় l1পুনরাবৃত্ত উপাদানগুলি অন্তর্ভুক্ত থাকলে এই পদ্ধতিটি কাজ করবে না ।
jdhao

10

সেট কমারহেনশনগুলি {x ব্যবহার করুন x এর জন্য l2} বা সেট (l2) পেতে সেট করুন, তারপরে তালিকা পেতে তালিকা বোঝার ব্যবহার করুন

l2set = set(l2)
l3 = [x for x in l1 if x not in l2set]

মানদণ্ড পরীক্ষার কোড:

import time

l1 = list(range(1000*10 * 3))
l2 = list(range(1000*10 * 2))

l2set = {x for x in l2}

tic = time.time()
l3 = [x for x in l1 if x not in l2set]
toc = time.time()
diffset = toc-tic
print(diffset)

tic = time.time()
l3 = [x for x in l1 if x not in l2]
toc = time.time()
difflist = toc-tic
print(difflist)

print("speedup %fx"%(difflist/diffset))

মানদণ্ড পরীক্ষার ফলাফল:

0.0015058517456054688
3.968189239501953
speedup 2635.179227x    

1
l2set = set( l2 )পরিবর্তেl2set = { x for x in l2 }
সিজেড

1
সুন্দর আত্মা! তবে এটি অবশ্যই মাথায় রাখতে হবে, এটি কেবল ধাবনযোগ্য বস্তুর সাথে কাজ করে।
এরিক সোভেন পিউডিস্ট

7

বিকল্প সমাধান:

reduce(lambda x,y : filter(lambda z: z!=y,x) ,[2,3,5,8],[1,2,6,8])

2
এই পদ্ধতিটি ব্যবহার করে কি কোনও সুবিধা আছে? দেখে মনে হচ্ছে এটি খুব জটিল এবং বেশি সুবিধা ছাড়াই পড়া শক্ত।
skrrgwasme

এটা জটিল মনে হতে পারে। হ্রাস খুব নমনীয় এবং অনেকগুলি উদ্দেশ্যে ব্যবহার করা যেতে পারে। এটি ভাঁজ হিসাবে পরিচিত। হ্রাস আসলে ভাঁজ হয়। মনে করুন আপনি এটিতে আরও জটিল স্টাফ যুক্ত করতে চান তবে এই ফাংশনে এটি সম্ভব হবে তবে নির্বাচিত সেরা উত্তরটি তালিকার বোধগম্যতা আপনাকে একই ধরণের আউটপুট প্রদান করবে যেমন তালিকা এবং সম্ভবত একই দৈর্ঘ্যের আপনি ভাঁজগুলি সহ করতে পারেন আউটপুট টাইপ পরিবর্তন করুন। en.wikedia.org/wiki/Fold_%28higher-order_function%29 । এই সমাধানটি এন * মি বা কম জটিলতা। অন্যরা হয়ত ভাল নাও হতে পারে।
অক্ষয় হাজারী

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