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