مقایسه لیست ها در پایتون — راهنمای به زبان ساده
در زبان برنامهنویسی پایتون، لیست را میتوان به عنوان یکی از پرکاربردترین ساختارهای داده تلقی کرد. در پایتون از لیست برای ذخیره کردن چندین آیتم مختلف در یک متغیر استفاده میشود. در طی نوشتن کدهای پایتون، ممکن است نیاز باشد که مقادیر ذخیره شده در ساختار داده لیست مورد مقایسه قرار بگیرند. در مقاله حاضر سعی شده است تا حد امکان بهطور جامع به معرفی ساختار داده لیست پرداخته و انواع روشهای موجود برای مقایسه لیست ها در پایتون به همراه مثال شرح داده شوند.
لیست در پایتون چیست ؟
لیست به عنوان یکی از رایجترین و پرکاربردترین ساختار دادههای پایتون محسوب میشود که از آن میتوان برای ذخیره آیتمهای مختلف استفاده کرد. لیست در پایتون مشابه ساختار داده آرایه در سایر زبانهای برنامهنویسی است؛ با این حال، تفاوت اصلی لیست با آرایه در این است که لیستها برخلاف آرایهها میتوانند مقادیری با «نوع داده» (Data Type) مختلف را ذخیره کنند.
ویژگی های مهم لیست در پایتون چه هستند ؟
لیستهای پایتون از ویژگیهای مهمی برخوردارند. این ویژگیها عبارتاند از:
- لیستها قابل تغییر هستند. به عبارتی، بعد از تعریف لیست، میتوان آیتمهای آن را تغییر داد.
- لیستها آیتمهای خود را به ترتیب ذخیره میکنند. البته میتوان ترتیب آیتمهای درون لیست را تغییر داد.
- لیستها از اندیسگذاری برای دسترسی به آیتم خاصی استفاده میکنند.
- لیستها میتوانند مقادیر تکراری را در خود ذخیره کنند.
- میتوان در پایتون لیستهای تودرتو ایجاد کرد. به عبارتی، یکی از آیتمهای لیستها میتواند لیست دیگری باشد.
تعریف لیست در پایتون چگونه انجام میشود ؟
بهمنظور تعریف لیست در پایتون از علامت (براکت | [ ] ) استفاده میشود. هر یک از آیتمهای درون لیست نیز، با علاکت ویرگول انگلیسی (کاما) از یکدیگر جدا میشوند. در مثال زیر، سه نمونه از لیست با دادههای متفاوت ملاحظه میشود.
1list1 = ['physics', 'chemistry', 1997, 2000]
2list2 = [1, 2, 3, 4, 5 ]
3list3 = ["a", "b", "c", "d"]
در ادامه مطلب، به توضیح روشهای مختلف برای مقایسه دو لیست در پایتون پرداخته میشود.
روش های مقایسه لیست ها در پایتون کدامند ؟
مقایسه لیست در پایتون روشی است که با آن میتوان تعیین کرد آیا مقادیر موجود در لیستها با یکدیگر برابر هستند یا تفاوتهایی در آیتمهای لیستها وجود دارد. برای مقایسه دو لیست میتوان حالات پیچیدهتری را در نظر گرفت. هر یک از این حالتها در ادامه فهرست شدهاند:
- مقایسه دو لیست با مقادیر اعشاری با در نظر گرفتن «حد مجاز خطا» (Tolerance)
- مقایسه لیست ها در پایتون بدون در نظر داشتن ترتیب قرار گرفتن مقادیر در لیستها
- مقایسه لیست در پایتون و پیدا کردن مقادیر مشترک لیستها
- مقایسه دو لیست در پایتون و پیدا کردن مقادیر غیرمشترک لیستها
- مقایسه لیست ها در پایتون با مقادیر رشتهای بدون در نظر گرفتن حروف بزرگ و کوچک رشتهها
- مقایسه لیست در پایتون با مقادیر «دیکشنری» (Dictionary)
در ادامه مطلب، به توضیح روشهای مقایسه لیست ها در پایتون برای اعداد صحیح پرداخته شده است و محدودیت هر یک از روشهای مقایسه لیست شرح داده میشود. سپس، به توضیح روشهای مقایسه برای سایر انواع داده نظیر اعداد اعشاری، رشتهها، دیکشنری و لیستهای تودرتو نیز پرداخته ميشود.
استفاده از عملگر == برای مقایسه لیست ها در پایتون
یکی از سادهترین و رایجترین روش برای مقایسه لیست در پایتون، استفاده از عملگر==است. از این روش، در شرایط پیچیدهتر مقایسه استفاده نمیشود. در این روش مقایسه، آیتمهای درون دو لیست، یک به یک با یکدیگر مقایسه میشوند و چنانچه تمامی مقادیر با یکدیگر برابر بودند، خروجی این عملگر مقدار True خواهد بود؛ در غیر این صورت، در خروجی مقدار False بازگردانده میشود.
در مثال زیر، دو لیستnumbers وtarget با مقادیر عددی وجود دارند که با عملگر==مورد مقایسه قرار گرفتهاند. با این که محتوای هر دو لیست، یکسان هستند، با جابجایی دو آیتم در یکی از این لیستها، مقدار خروجی برابر با False میشود. بدین ترتیب، از این عملگر برای مقایسه دو لیست در پایتون بدون درنظر گرفتن ترتیب قرارگیری مقادیر در لیستها نمیتوان استفاده کرد.
1>>> numbers = [1, 2, 3]
2>>> target = [1, 2, 3]
3>>> numbers == target
4True
5>>> [1, 2, 3] == [1, 3, 2]
6False
استفاده از تابع Sort() و عملگر == برای مقایسه لیست در پایتون
در روش قبل ملاحظه شد هنگامی که دو لیست در پایتون دارای آیتمهای یکسانی هستند و تنها در ترتیب قرارگیری آیتمها با یکدیگر مغایرت دارند، عملگر==به تنهایی نمیتواند خروجی صحیحی برای مقایسه دو لیست در پایتون داشته باشد. یکی از راهحلهای پیشنهادی برای رفع این مشکل، استفاده از تابعsort است. با استفاده از این تابع، آیتمهای درون لیستها را میتوان مرتب کرد و سپس با استفاده از عملگر==مقایسه لیستها را انجام داد.
قطعه کد زیر، نمونهای از مقایسه دو لیست در پایتون را با استفاده از تابعsort و عملگر== نشان میدهد.
1l1 = [10, 20, 30, 40, 50]
2l2 = [10, 20, 30, 50, 40, 70]
3l3 = [50, 10, 30, 20, 40]
4
5l1.sort()
6l2.sort()
7l3.sort()
8
9if l1 == l3:
10 print ("The lists l1 and l3 are the same")
11else:
12 print ("The lists l1 and l3 are not the same")
13
14
15if l1 == l2:
16 print ("The lists l1 and l2 are the same")
17else:
18 print ("The lists l1 and l2 are not the same")
همانطور که در قطعه کد فوق ملاحظه میشود، لیستهایl1 ،l2 وl3 در ابتدا با استفاده از تابعsort مرتب و در ادامه با استفاده از عملگر== مقایسه شدهاند. خروجی قطعه کد بالا به صورت زیر است.
The lists l1 and l3 are the same The lists l1 and l2 are not the same
استفاده از تابع Set() و عملگر == برای مقایسه لیست ها در پایتون
استفاده از تابع «مجموعه» (Set) روش دیگری در زبان برنامهنویسی پایتون است که مشکل ترتیب آیتمهای درون لیست را برای مقایسه چندین لیست برطرف میکند. به عبارتی، در ساختار دادهset ترتیب قرارگیری آیتمهای درون مجموعه در نظر گرفته نمیشود و میتوان صرفاً مقادیر درون مجموعه را با یکدیگر مقایسه کرد.
در قطعه کد زیر، مثالی از مقایسه دو مجموعه در پایتون ملاحظه میشود.
1l1 = [10, 20, 30, 40, 50]
2l2 = [50, 10, 30, 20, 40]
3
4a = set(l1)
5b = set(l2)
6
7if a == b:
8 print("Lists l1 and l3 are equal")
9else:
10 print("Lists l1 and l3 are not equal")
بر اساس قطعه کد فوق، در ابتدا دو لیستl1 وl2 با استفاده از دستورset() به دو مجموعهa وb تبدیل شدهاند و سپس آیتمهای درون مجموعهها با استفاده از عملگر== مورد مقایسه قرار گرفتند. خروجی قطعه کد بالا در زیر ملاحظه میشود.
Lists l1 and l3 are equal
استفاده از کتابخانه deepdiff برای مقایسه لیست ها در پایتون چگونه است؟
کتابخانهdeepdiff روشی دیگری برای مقایسه لیست ها در پایتون محسوب میشود. برای استفاده از این کتابخانه، در ابتدا باید آن را برروی سیستم نصب کرد. این کتابخانه، دو لیست را به عنوان ورودی در زبان پایتون دریافت میکند و در خروجی، مقادیر متمایز را برمیگرداند. کتابخانهdeepdiffبه صورت پیشفرض ترتیب قرارگیری آیتمهای درون لیستها را مد نظر قرار میدهد؛ اما میتوان از پارامتر این کتابخانه با نامignore_order استفاده کرد تا در حین مقایسه دو لیست، ترتیب قرارگیری مقادیر نادیده گرفته شود.
قطعه کد زیر، مثالی از کاربرد کتابخانهdeepdiffرا برای مقایسه لیست در پایتون نشان میدهد.
1In [11]: numbers = [10, 30, 20]
2
3In [12]: target = [10, 20, 30]
4
5In [13]: DeepDiff(numbers, target)
6Out[13]:
7{'values_changed': {'root[1]': {'new_value': 20, 'old_value': 30},
8 'root[2]': {'new_value': 30, 'old_value': 20}}}
9
10In [14]: DeepDiff(numbers, target, ignore_order=True)
11Out[14]: {}
معرفی فیلم های آموزش پایتون
سایت فرادرس یک مجموعه آموزشی برای علاقمندان به یادگیری زبان برنامهنویسی پایتون فراهم کرده است. امروزه، پایتون به عنوان یکی از زبانهای برنامهنویسی رایج در حوزههای مختلف، در اکثر پروژههای برنامهنویسی کاربرد دارد. افراد علاقمند به این زبان میتوانند از مجموعه فیلمهای آموزشی پایتون در سایت فرادرس استفاده کنند. این دورههای آموزشی شامل فیلمهای آموزشی مقدماتی تا پیشرفته و پروژهمحور زبان پایتون میشوند. در تصویر فوق تنها برخی از دورههای آموزشی مجموعه آموزش پایتون فرادرس نمایش داده شدهاند.
- برای دسترسی به همه آموزش های پایتون فرادرس + اینجا کلیک کنید.
استفاده از دستور For به همراه عملگر == برای مقایسه دو لیست در پایتون
یکی دیگر از روشهای رایج برای مقایسه لیست ها در پایتون استفاده از حلقهfor به همراه عملگر== است. در این روش، با استفاده از حلقه، آیتمهای درون لیستها یک به یک با یکدیگر مقایسه میشوند. این روش، مشابه اولین روشی است که در این مقاله شرح داده شد، اما به دلیل استفاده از حلقهfor، در این روش محاسبات بیشتری انجام میشود. از این روش افراد تازهکار در برنامهنویسی استفاده میکنند، زیرا با نحوه کار با عملگر==آشنا نیستند. به عبارتی، عملگر==را میتوان برای مقایسه یکبهیک آیتمهایی استفاده کرد که در متغیری ذخیره شدهاند که دارای ویژگی «قابلیت تکرار» (Iterable) هستند. در این حالت، تنها با نوشتن یک دستورlist1 == list2 ، میتوان بدون استفاده از حلقهfor،آیتمهای دو لیست را با یکدیگر مقایسه کرد و بدین ترتیب بار محاسباتی آن کمتر است.
قطعه کد زیر، مثالی از روش مقایسه لیست در پایتون را نشان میدهد.
1# 2. Simple For Loop
2def comparison(l1, l2):
3 for i in range(min(len(l1), len(l2))):
4 if l1[i] != l2[i]:
5 return False
6 return len(l1) == len(l2)
7l1 = [1, 2, 3, 4, 5]
8l2 = [1, 2, 3]
9print(comparison(l1, l2))
در قطعه کد بالا ملاحظه میشود که روند مقایسه دو لیست در حلقهforاز اندیس 0 شروع میشود و روند مقایسه تا اندیس پایانی کوتاهترین لیست ادامه پیدا میکند. کمترین طول دو لیستl1 وl2 نیز با دستورmin(len(l1), len(l2)) مشخص میشود. با دستورl1[i] != l2[i] میتوان بررسی کرد آیا هر یک از آیتمهای دو لیست با یکدیگر برابر هستند یا خیر؟ چنانچه هر یک از آیتمهای دو لیست با یکدیگر برابر نبودند، مقدار False به عنوان خروجی تابعcomparison برگردانده میشود و کار مقایسه دو لیست به اتمام میرسد.
در مثال بالا، در صورتی که تکرار حلقهforتا انتهای لیست ادامه پیدا میکرد و خروجی تابع مقدار False نبود، به این معنی است که تمام آیتمهای دو لیست با هم برابرند. بهمنظور بررسی یکسان بودن طول هر دو لیست نیز، از دستورlen(l1) == len(l2)استفاده شده است. با به کار بردن این دستور، میتوان اطمینان پیدا کرد که تعداد عناصر هر دو لیست مشابه هم هستند و طول دو لیست با یکدیگر برابر است.
با اضافه کردن دستورprint(l1) در قسمتelse نیز میتوان مقادیر مشترک هر دو لیست را در خروجی ملاحظه کرد.
1# 2. Simple For Loop
2def comparison(l1, l2):
3 for i in range(min(len(l1), len(l2))):
4 if l1[i] != l2[i]:
5 return False
6 else:
7 print(l1)
8 return len(l1) == len(l2)
9
10l1 = [1, 2, 3, 4, 5]
11l2 = [1, 2, 3]
12print(comparison(l1, l2))
استفاده از تابع Zip() و حلقه For برای مقایسه لیست در پایتون
تابعzip مقادیر iامین آیتم لیستها را با یکدیگر ترکیب میکند و برای هر جفت آیتم، «تاپل» (Tuple) میسازد. در این حالت دیگر نیاز نیست برای اشاره به مقادیر لیستها، از اندیس استفاده شود. بنابراین، در مقایسه با روش قبل، تابعzipاز میزان پیچیدگی کدنویسی کم میکند.
1# 3. Zip + For Loop
2def comparison(l1, l2):
3 for x, y in zip(l1, l2):
4 if x != y:
5 return False
6 return len(l1) == len(l2)
7l1 = [1, 2, 3, 4, 5]
8l2 = [1, 2, 3]
9print(comparison(l1, l2))
بر اساس قطعه کد فوق، چنانچه طول دو لیست با یکدیگر برابر نباشد، تابعzipآیتمهای اضافی لیست طولانیتر را نادیده میگیرد. این روش مقایسه لیستها در پایتون همچنان دارای بار محاسباتی زیادی است زیرا در این روش از حلقهforاستفاده میشود.
استفاده از توابع Sum() ،Zip() و Len() برای مقایسه لیست ها در پایتون
در روشهای قبل از حلقهforبهمنظور مقایسه آیتمهای دو لیست در پایتون استفاده شد. برنامهنویسان حرفهای همیشه سعی دارند تا جایی که امکان دارد، درون کد خود از حلقه استفاده نکنند تا بار محاسباتی کدها کاهش پیدا کند.
راهحل جایگزین حلقهها، استفاده از دستورات «مولد» (Generator) است. در قطعه کد زیر، از دستورx == y for x, y in zip(l1, l2) به عنوان Generator استفاده شده است تا بار محاسباتی کاهش یابد. خروجی نهایی قطعه کد زیر برابر با False است.
1# 4. Sum + Zip + Len
2def comparison(l1, l2):
3 num_equal = sum(x == y for x, y in zip(l1, l2))
4 return num_equal == len(l1) == len(l2)
5
6l1 = [1, 2, 3, 4, 5]
7l2 = [1, 2, 3]
8print(comparison(l1, l2))
بر اساس قطعه کد بالا، ملاحظه میشود که:
- در ابتدا، مقادیر دو لیستl1 وl2 یک به یک با یکدیگر مقایسه میشوند.
- تابعsum تعداد آیتمهایی را میشمارد که در هر دو لیستl1وl2با یکدیگر برابر هستند. در نهایت، تعداد آیتمهای مشابه در متغیری با عنوانnum_equal ذخیره میشود.
- در آخر، مقدار متغیرnum_equalبا مقدار طول هر دو لیستl1وl2مقایسه میشود. اگر هر سه مقدار با یکدیگر برابر باشند، آیتمهای دو لیست با یکدیگر مشابه خواهند بود.
استفاده از توابع Reduce() ،Map() و Len() برای مقایسه لیست در پایتون
«برنامهنویسی تابعی» (Functional Programming) روش دیگری است که برای مقایسه لیست ها در پایتون استفاده میشود. در این رویکرد از برنامهنویسی، به جای استفاده از دستورات شرطی و حلقه، از توابع استفاده میشود.
1# 5. map() + reduce() + len()
2from functools import reduce
3def comparison(l1, l2):
4 equal = map(lambda x, y: x == y, l1, l2)
5 result = reduce(lambda x, y: x and y, equal)
6 return result and len(l1) == len(l2)
7
8l1 = [1, 2, 3, 4, 5]
9l2 = [1, 2, 3]
10print(comparison(l1, l2))
بر اساس قطعه کد فوق، از تابعmap بهمنظور مقایسه آیتمهای دو لیستl1 وl2استفاده شده است. از تابعreduce نیز بهمنظور ترکیب تمام مقادیر بولی حاصل از تابع استفاده میشود که در مثال فوق، مقدار نهایی متغیرresult برابر با True است. در نهایت، طول دو لیست بررسی میشود که در این مثال، طول دو لیست با یکدیگر برابر نیست. بدین ترتیب، تابعcomparison مقدار False را در خروجی برمیگرداند.
استفاده از توابع All() ،Map() و Len() برای مقایسه دو لیست در پایتون
به جای استفاده از تابعreduce در روش قبل، میتوان از تابعall استفاده کرد. تابعall بررسی میکند آیا تمام آیتمهای ساختار دادهها نظر لیست برابر با True هستند؟ چنانچه یکی از آیتمهای ساختار دادهها برابر با False باشند، خروجی این تابع نیز برابر با False خواهد بود. در مثال زیر، نحوه استفاده از تابعallبرای مقایسه دو لیست در پایتون ملاحظه میشود.
1# 6. map() + all()
2def comparison(l1, l2):
3 result = all(map(lambda x, y: x == y, l1, l2))
4 return result and len(l1) == len(l2)
5l1 = [1, 2, 3, 4, 5]
6l2 = [1, 2, 3]
7print(comparison(l1, l2))
بر اساس قطعه کد فوق، خروجی تابعcomparison برابر با False است زیرا طول دو لیستl1 وl2 با یکدیگر برابر نیست.
استفاده از متد collection.counter() برای مقایسه لیست ها در پایتون
متدcollection.counter() روش کارامدی برای مقایسه لیست در پایتون محسوب میشود. تابعcounter() تعداد تکرار هر آیتم در لیست را میشمارد و در قالب دیکشنری با فرمت value : frequency ذخیره میکند. چناچه خروجی دیکشنری هر دو لیست مشابه بود، دو لیست دارای مقادیر مشابهی هستند.
در قطعه کد زیر، مثالی از مقایسه دو لیست در پایتون با استفاده از تابعcollection.counter()ارائه شده است.
1import collections
2
3
4l1 = [10, 20, 30, 40, 50]
5l2 = [10, 20, 30, 50, 40, 70]
6l3 = [10, 20, 30, 40, 50]
7
8if collections.Counter(l1) == collections.Counter(l2):
9 print ("The lists l1 and l2 are the same")
10else:
11 print ("The lists l1 and l2 are not the same")
12
13if collections.Counter(l1) == collections.Counter(l3):
14 print ("The lists l1 and l3 are the same")
15else:
16 print ("The lists l1 and l3 are not the same")
خروجی قطعه کد فوق در زیر ملاحظه میشود.
The lists l1 and l2 are not the same The lists l1 and l3 are the same
یافتن مقادیر مشترک موجود در لیست ها در پایتون
بهمنظور یافتن مقادیر مشترک موجود در لیستها، میتوان از متدintersection ساختار داده مجموعه (Set) استفاده کرد. چنانچه مقادیر مورد نظر، در لیستهای مجزا ذخیره شده باشند، در ابتدا باید آنها را در قالب دو مجموعه ذخیره کرد تا بتوان متدintersectionمربوط بهsetرا بهمنظور یافتن آیتمهای مشترک دو مجموعه به کار برد.
مثال زیر، نمونهای از کاربرد متدintersectionرا برای پیدا کردن مقادیر مشترک دو لیست نشان میدهد. در ابتدا، مقادیر دو لیستl1 وl2 در ساختار داده Set ذخیره شده و سپس از متدintersectionاستفاده شده است.
1In [1]: t1 = [2, 1, 0, 7, 4, 9, 3]
2
3In [2]: t2 = [7, 6, 11, 12, 9, 23, 2]
4
5In [3]: set(t1).intersection(set(t2))
6Out[3]: {2, 7, 9}
از علامت& نیز میتوان به جای متدintersectionبه صورت زیر استفاده کرد.
1# the & operator is a shorthand for the set.intersection() method
2In [4]: set(t1) & set(t2)
3Out[4]: {2, 7, 9}
یافتن مقادیر غیرمشترک دو لیست در پایتون
بهمنظور پیدا کردن مقادیر غیرمشترک لیستها در پایتون، میتوان از چندین روش استفاده کرد که در ادامه فهرست شدهاند:
- استفاده از ساختار داده مجموعه در پایتون
- به کارگیری متد Difference ساختار داده Set
- استخراج آیتمهای متفاوت دو لیست در پایتون با استفاده از کتابخانه Deepdiff
- یافتن مقادیر غیرمشترک لیستهای پایتون با List Comprehension
- استفاده از حلقه For برای یافتن مقادیر مغایر دو لیست در پایتون
در ادامه مطلب، به توضیح هر یک از روشهای یافتن مقادیر مغایر در لیستها پرداخته میشود.
استفاده از مجموعه برای یافتن مقادیر غیرمشترک لیست ها در پایتون
از ساختار داده مجموعه میتوان بهمنظور یافتن مقادیر غیرمشترک لیستها استفاده کرد. به عبارتی، میتوان لیستهای پایتون را با استفاده از دستورset به ساختار داده مجموعه تبدیل کرد و سپس با استفاده از عملگر- مقادیری را در خروجی بازگرداند که در مجموعه اول وجود دارند اما مجموعه دوم این مقادیر را شامل نمیشود.
در مثال زیر، نمونهای از کاربرد مجموعه بهمنظور یافتن مقادیر غیرمشترک دو لیست در پایتون ملاحظه میشود.
1a = [5, 4, 3, 2, 1]
2b = [4, 5, 6, 7]
3
4print(set(a) - set(b))
5# {1, 2, 3}
6print(set(b) - set(a))
7# {6, 7}
لازم به ذکر است که این روش، دارای ویژگیهایی به شرح ذیل است:
- نتیجه نهایی تفاضل دو مجموعه، از نوع Set است و برای تبدیل خروجی عملگر-به ساختار داده لیست، باید از دستورlist()استفاده کرد.
- چنانچه مقادیر تکراری در لیست وجود داشته باشند، در حین تبدیل لیست به ساختار داده مجموعه، این مقادیر حذف میشوند زیرا ساختار داده Set نمیتواند شامل مقادیر تکراری باشد.
- با تبدیل کردن لیست به ساختار داده Set، ترتیب مقادیر لیستها نیز از بین میرود.
چنانچه برای یافتن مقادیر غیرمشترک لیستها در پایتون هیچ یک از ویژگیهای ذکر شده در بالا برای پروژه برنامهنویسی مسئلهساز نیستند، میتوان از این روش استفاده کرد.
استفاده از متدهای Difference و Symmetric_Difference در نوع مجموعه برای یافتن مقادیر غیرمشترک لیست ها در پایتون
ساختار داده مجموعه در پایتون دارای متدی به نامdifference است که با استفاده از آن میتوان مقادیری را در خروجی بازگرداند که در مجموعه اول وجود دارند اما مجموعه دوم این مقادیر را شامل نمیشود. همچنین، میتوان با استفاده از متدsymmetric_difference تمامی مقادیر غیرمشترک دو مجموعه در پایتون را استخراج کرد.
قطعه کد زیر، مثالی از کاربرد دو متدdifferenceوsymmetric_differenceرا بهمنظور یافتن مقادیر غیرمشترک لیستها در پایتون نشان میدهد.
1In [8]: t1 = [2, 1, 0, 7, 4, 9, 3]
2In [9]: t2 = [7, 6, 11, 12, 9, 23, 2]
3
4In [10]: set(t1).difference(set(t2))
5Out[10]: {0, 1, 3, 4}
6
7In [11]: set(t2).difference(set(t1))
8Out[11]: {6, 11, 12, 23}
9
10In [12]: set(t1).symmetric_difference(set(t2))
11Out[12]: {0, 1, 3, 4, 6, 11, 12, 23}
لازم به ذکر است هنگامی که از متدsymmetric_differenceبرای یافتن مقادیر غیرمشترک مجموعههای پایتون استفاده میشود، نمیتوان مشخص کرد کدام یک از مقادیر بازگردانده شده توسط این متد، مربوط به چه مجموعهای هستند. به عبارتی، بر اساس قطعه کد فوق، ملاحظه میشود که خروجی این متد، ترکیبی از مقادیر مغایر دو مجموعه ورودی است و بر اساس مجموعههای ورودی این تابع، تفکیکی در خروجی انجام نشده است.
استفاده از کتابخانه Deepdiff برای یافتن مقادیر غیرمشترک لیست در پایتون
از کتابخانهdeepdiffمیتوان بهمنظور یافتن مقادیر مغایر لیستها در پایتون استفاده کرد. کتابخانهdeepdiffبه طور پیشفرض ترتیب قرارگیری آیتمهای درون لیستها را مد نظر قرار میدهد؛ اما میتوان از پارامتر این کتابخانه با نامignore_order استفاده کرد و مقدار این پارامتر را برابر با True قرار داد تا در حین مقایسه دو لیست، ترتیب قرارگیری مقادیر نادیده گرفته شود. خروجی این تابع از نوع دیکشنری است که مقادیر مغایر دو لیست ورودی خود را نشان میدهد.
در قطعه کد زیر، مثالی از کاربرد کتابخانه deepdiff بهمنظور یافتن مقادیر غیرمشترک لیستها در پایتون ارائه شده است.
1In [15]: t1 = [2, 1, 0, 7, 4, 9, 3]
2In [16]: t2 = [7, 6, 11, 12, 9, 23, 2]
3
4In [17]: DeepDiff(t1, t2)
5Out[17]:
6{'values_changed': {'root[0]': {'new_value': 7, 'old_value': 2},
7 'root[1]': {'new_value': 6, 'old_value': 1},
8 'root[2]': {'new_value': 11, 'old_value': 0},
9 'root[3]': {'new_value': 12, 'old_value': 7},
10 'root[4]': {'new_value': 9, 'old_value': 4},
11 'root[5]': {'new_value': 23, 'old_value': 9},
12 'root[6]': {'new_value': 2, 'old_value': 3}}}
13
14In [18]: DeepDiff(t1, t2, ignore_order=True)
15Out[18]:
16{'values_changed': {'root[4]': {'new_value': 6, 'old_value': 4},
17 'root[6]': {'new_value': 11, 'old_value': 3},
18 'root[1]': {'new_value': 12, 'old_value': 1}},
19 'iterable_item_added': {'root[5]': 23},
20 'iterable_item_removed': {'root[2]': 0}}
لازم به ذکر است چنانچه خروجی تابعdeepdiffبرابر با دیکشنری تهی باشد، دو لیست ورودی این تابع شامل مقادیر یکسان هستند.
استفاده از List Comprehension برای یافتن مقادیر غیرمشترک دو لیست در پایتون
یکی از سریعترین روشها برای ایجاد کردن لیست در پایتون، استفاده از List Comprehension است. روش استفاده از List Comprehension در پایتون به صورت[expression + context] است که عبارتاند از:
- Expression: گویای این است که برروی کدام آیتمهای لیست باید تغییرات (دستورات) اعمال شود.
- Context: شامل دستورات شرطیif وfor حلقه است.
قطعه کد زیر، مثالی از کاربرد List Comprehension را بهمنظور یافتن مقادیر غیرمشترک لیستها در پایتون نشان میدهد.
1a = [5, 4, 3, 2, 1]
2b = [4, 5, 6, 7]
3
4# Method: List Comprehension
5print([x for x in a if x not in set(b)])
6# [3, 2, 1]
در قطعه کد فوق ملاحظه میشود که با استفاده از دستورset(b) ، لیستb به ساختار داده Set تبدیل شده است. به دلیل آن که روش جستجوی مقادیر در ساختار داده Set پایتون با استفاده از دستورx in b سریعتر انجام میشود، در مثال بالا ساختار داده لیست به ساختار داده مجموعه تبدیل شده است.
ویژگیهای استفاده از روش List Comprehension بهمنظور پیدا کردن مقادیر غیرمشترک لیستهای پایتون به شرح زیر است:
- خروجی دستور List Comprehension از نوع ساختار داده لیست است.
- ترتیب آیتمهای لیستها در این روش حفظ میشود.
- مقادیر تکراری موجود در لیستها از بین نمیروند.
استفاده از حلقه For برای یافتن مقادیر مغایر دو لیست در پایتون
یکی دیگر از روشهای پیدا کردن مقادیر غیرمشترک دو لیست در پایتون، استفاده از حلقههایfor تودرتو است. این روش مناسب افراد تازهکار در زبان برنامهنویسی پایتون است که با ویژگیهای مهم پایتون نظیر List Comprehension آشنایی ندارند.
قطعه کد زیر، مثالی از کاربرد حلقههای تودرتویforرا نشان میدهد که مقادیر مغایر دو لیست را در خروجی برمیگرداند.
1# Method: Nested For Loop
2a = [5, 4, 3, 2, 1]
3b = [4, 5, 6, 7]
4d = []
5for x in a:
6 if x not in b:
7 d.append(x)
8print(d)
9# [3, 2, 1]
در مثال فوق نیز، میتوان لیستb را به ساختار داده Set تبدیل کرد تا عمل جستجو با دستورx not in b سریعتر انجام شود.
مقایسه لیستی از اعداد اعشاری در پایتون
بهترین روش برای مقایسه لیستهایی که شامل مقادیری از نوع اعداد اعشاری هستند، استفاده از کتابخانهdeepdiffاست. با استفاده از این کتابخانه میتوان مشخص کرد که در حین مقایسه دو عدد، چه تعداد رقم بعد از اعشار لحاظ شود. به عبارتی، این کتابخانه دارای پارامتری با عنوانsignificant_digits است که با استفاده از آن میتوان تعداد ارقام بعد از اعشار را برای مقایسه تعیین کرد.
قطعه کد زیر، مثالی از کاربرد کتابخانهdeepdiffرا برای مقایسه اعداد اعشاری دو لیست نشان میدهد.
1In [1]: from deepdiff import DeepDiff
2
3In [2]: numbers = [0.3000000000000000004, 0.2]
4In [3]: target = [0.3, 0.2]
5
6# if we don't specify the number of significant digits, the comparison will use ==
7In [4]: DeepDiff(numbers, target)
8Out[4]:
9{'values_changed': {'root[0]': {'new_value': 0.3,
10 'old_value': 0.30000000000000004}}}
11
12# 0.30000000000000004 and 0.3 are equal if we only look at the first 3 significant digits
13In [5]: DeepDiff(numbers, target, significant_digits=3)
14Out[5]: {}
همانطور که در قطعه کد فوق ملاحظه میشود، زمانی که تعداد اعداد بعد اعشار برای مقایسه دو لیست مشخص نشده باشد، هر دو آیتم نخست لیستهایnumbers وtarget مغایر هم در نظر گرفته میشود؛ در حالی که با تعیین مقدار عددی 3 برای پارامترsignificant_digits، دو آیتم نخست لیستها یکسان تلقی میشوند.
مقایسه لیستی از رشته ها در پایتون
بهمنظور مقایسه لیستهایی که شامل مقادیری از نوع رشته هستند، میتوان از دو روش زیر استفاده کرد:
- استفاده از عملگر== برای مقایسه لیستی از رشتهها در پایتون
- مقایسه لیستی از رشتهها با کتابخانه deepdiff در پایتون
در ادامه مطلب، به توضیح هر یک از روشهای فوق به همراه مثال پرداخته میشود.
استفاده از عملگر == برای مقایسه لیستی از رشتهها در پایتون
با استفاده از عملگر==میتوان دو لیست با مقادیر رشته را با یکدیگر مقایسه کرد. ترتیب آیتمها در این روش مهم هستند. در زیر، نمونهای از کاربرد عملگر==برای مقایسه رشتههای موجود در دو لیست ملاحظه میشود.
1In [1]: names = ['jack', 'josh', 'james']
2In [2]: target = ['jack', 'josh', 'james']
3
4In [3]: names == target
5Out[3]: True
همچنین، این روش به بزرگ یا کوچک بودن حروف حساس است. در مثال زیر ملاحظه میشود که با تغییر دادن اولین حروف رشتهها به حروف بزرگ، خروجی عملگر==برابر با مقدار False میشود.
1In [4]: names = ['Jack', 'Josh', 'James']
2In [2]: target = ['jack', 'josh', 'james']
3
4In [5]: names == target
5Out[5]: False
استفاده از کتابخانه Deepdiff برای مقایسه لیستی از رشتهها در پایتون
از کتابخانهdeepdiff میتوان برای مقایسه رشتههای موجود در لیستهای پایتون استفاده کرد. با استفاده از پارامتر این کتابخانه با عنوانignore_order میتوان مشخص کرد آیا ترتیب آیتمهای رشتهای درون لیستها برای مقایسه مهم هستند یا نیازی نیست ترتیب قرارگیری آنها را در لیست مد نظر قرار داد. علاوه بر این، میتوان با استفاده از پارامترignore_string_case معین کرد که در حین مقایسه رشتهها، حروف بزرگ و کوچک از هم متمایز شوند یا این ویژگی در نظر گرفته نشود.
قطعه کد زیر، مثالی از کاربرد کتابخانهdeepdiffرا برای مقایسه رشتههای دو لیست نشان میدهد.
1In [6]: names = ['Jack', 'James', 'Josh']
2In [7]: target = ['jack', 'josh', 'james']
3
4# ignoring the order and string case
5In [8]: deepdiff.DeepDiff(names, target, ignore_string_case=True, ignore_order=True)
6Out[8]: {}
7
8# considering the order but ignoring the case
9In [9]: deepdiff.DeepDiff(names, target, ignore_string_case=True)
10Out[9]:
11{'values_changed': {'root[1]': {'new_value': 'josh', 'old_value': 'james'},
12 'root[2]': {'new_value': 'james', 'old_value': 'josh'}}}
مقایسه لیستی از دیکشنری ها در پایتون
مقایسه دو لیست با مقادیری از نوع دیکشنری در پایتون، بدون استفاده از کتابخانه پایتون بسیار پیچیده و دشوار است. بهمنظور سادگی انجام این کار، میتوان از کتابخانهdeepdiff استفاده کرد. در مثال زیر، نحوه استفاده از کتابخانهdeepdiffبرای مقایسه لیستی از دیکشنریها ملاحظه میشود.
1In [1]: from deepdiff import DeepDiff
2
3In [2]: first_list = [
4 {
5 'number': 1,
6 'list': ['one', 'two']
7 },
8 {
9 'number': 2,
10 'list': ['one', 'two']
11 },
12 ]
13
14In [3]: target_list = [
15 {
16 'number': 3,
17 'list': ['one', 'two']
18 },
19 {
20 'number': 2,
21 'list': ['one', 'two']
22 },
23 ]
24
25In [4]: DeepDiff(first_list, target_list)
26Out[4]: {'values_changed': {"root[0]['number']": {'new_value': 3, 'old_value': 1}}}
همانطور که در قطعه کد فوق ملاحظه میشود، خروجی تابعdeepdiffموقعیت آیتمی را در لیست دوم نشان میدهد که با آیتم لیست اول در موقعیت یکسان، مغایرت دارد.
قطعه کد زیر، مثال دیگری از لیستهایی است که دارای مقادیری از نوع دیکشنری هستند. در این مثال، لیست دوم، برخلاف لیست اول، تنها دارای یک آیتم از نوع دیکشنری است و طول دو لیست با یکدیگر برابر نیست.
1In [2]: first_list = [
2 {
3 'number': 1,
4 'list': ['one', 'two']
5 },
6 {
7 'number': 2,
8 'list': ['one', 'two']
9 },
10 ]
11
12In [5]: target = [
13 {
14 'number': 3,
15 'list': ['one', 'two']
16 },
17 ]
18
19In [6]:
20
21In [6]: DeepDiff(first_list, target)
22Out[6]:
23{'values_changed': {"root[0]['number']": {'new_value': 3, 'old_value': 1}},
24 'iterable_item_removed': {'root[1]': {'number': 2, 'list': ['one', 'two']}}}
همانطور که در خروجی قطعه کد فوق قابل ملاحظه است، تابعdeepdiffدر خروجی، موقعیت مکانی را با عنوانvalues_changed نشان میدهد که آیتمهای دو لیست در آن موقعیت با یکدیگر متفاوت هستند. همچنین، این تابع با استفاده از مقدارiterable_item_removed نشان میدهد که اولین لیست، مقداری اضافهتر از لیست دوم دارد.
مقایسه لیستی از لیست ها در پایتون
برای مقایسه لیستهای چندبعدی (لیستی از لیستها) نیز میتوان از کتابخانهdeepdiff استفاده کرد. در مثال زیر، دو لیست چندبعدی تعریف شده و با استفاده از کتابخانهdeepdiffمورد مقایسه قرار گرفتهاند.
1In [1]: from deepdiff import DeepDiff
2
3In [2]: first_list = [[1, 2], [3, 4], [[5]]]
4In [3]: target_list = [[1, 2], [8, 4], [[7]]]
5
6In [4]: DeepDiff(first_list, target_list)
7Out[4]:
8{'values_changed': {'root[1][0]': {'new_value': 8, 'old_value': 3},
9 'root[2][0][0]': {'new_value': 7, 'old_value': 5}}}
بر اساس خروجی قطعه کد فوق، ملاحظه میشود که کتابخانهdeepdiffموقعیت مکانی مقادیر مغایر دو لیست را نشان میدهد.
چنانچه دو لیست چندبعدی با مقادیر مشابه (همانند مثال زیر) به عنوان ورودی به کتابخانهdeepdiff داده شود، خروجی کتابخانه، دیکشنری تهی خواهد بود.
1In [3]: target_list = [[1, 2], [8, 4], [[7]]]
2In [5]: second_list = [[1, 2], [8, 4], [[7]]]
3
4In [7]: DeepDiff(second_list, target_list)
5Out[7]: {}
مقایسه لیستی از آرایه های numpy در پایتون
افرادی که در حوزه علم داده یا یادگیری ماشین فعالیت دارند، در پروژههای برنامهنویسی خود اغلب با مسئله مقایسه لیستهایی با مقادیر آرایههای numpy برخورد داشتهاند.
یکی از بهترین روشهای مقایسه این نوع آرایهها، استفاده از کتابخانهdeepdiff است. قطعه کد زیر، نمونهای از کاربرد این کتابخانه را برای مقایسه لیستی از آرایههای numpy نشان میدهد.
1In [16]: import numpy as np
2
3In [17]: from deepdiff import DeepDiff
4
5In [18]: first = [np.ones(3), np.array([1, 2, 3])]
6In [19]: target = [np.zeros(4), np.array([1, 2, 3, 4])]
7
8In [20]: DeepDiff(first, target)
9Out[20]:
10{'values_changed': {'root[0][0]': {'new_value': 0.0, 'old_value': 1.0},
11 'root[0][1]': {'new_value': 0.0, 'old_value': 1.0},
12 'root[0][2]': {'new_value': 0.0, 'old_value': 1.0}},
13 'iterable_item_added': {'root[0][3]': 0.0, 'root[1][3]': 4}}
جمعبندی
هدف از مقاله حاضر بررسی روشهای مختلف برای مقایسه انواع آیتمهای موجود در لیستهای پایتون بود. تشخیص بهترین روش مقایسه لیستهای پایتون به نوع آیتمهای ذخیره شده در لیست و شیوه مقایسه بستگی دارد. در این مقاله، به انواع روشهای مقایسه لیستها با مقادیر عددی صحیح و اعشاری، رشتهای، دیکشنری، لیستهای تودرتو و آرایههای numpy پرداخته شد. همچنین، توضیحات مربوط به توابع پایتون برای مقایسه لیستها و نحوه کار با آنها در قالب مثال ارائه شدند.
سلام وقت بخیر ممنون بابت توضیحات کامل و جامع عالی بود👏🏼 یه سوالی دارم: اگر بخوایم دو تا لیست که رشته ای هستند رو با هم مقایسه کنیم و مقادیر لیست کوچک تر رو از لیست بزرگتر حذف کنیم…چطوری میشه اینکا رو کرد؟