مقایسه لیست ها در پایتون — راهنمای به زبان ساده

۳۵۴۵ بازدید
آخرین به‌روزرسانی: ۲۱ اسفند ۱۴۰۲
زمان مطالعه: ۱۸ دقیقه
مقایسه لیست ها در پایتون — راهنمای به زبان ساده

در زبان برنامه‌نویسی پایتون، لیست را می‌توان به عنوان یکی از پرکاربردترین ساختارهای داده تلقی کرد. در پایتون از لیست‌ برای ذخیره کردن چندین آیتم مختلف در یک متغیر استفاده می‌شود. در طی نوشتن کدهای پایتون، ممکن است نیاز باشد که مقادیر ذخیره شده در ساختار داده لیست مورد مقایسه قرار بگیرند. در مقاله حاضر سعی شده است تا حد امکان به‌طور جامع به معرفی ساختار داده لیست پرداخته و انواع روش‌های موجود برای مقایسه لیست ها در پایتون به همراه مثال شرح داده شوند.

فهرست مطالب این نوشته

لیست در پایتون چیست ؟

لیست به عنوان یکی از رایج‌ترین و پرکاربردترین ساختار داده‌های پایتون محسوب می‌شود که از آن می‌توان برای ذخیره آیتم‌های مختلف استفاده کرد. لیست در پایتون مشابه ساختار داده آرایه در سایر زبان‌های برنامه‌نویسی است؛ با این حال، تفاوت اصلی لیست با آرایه در این است که لیست‌ها برخلاف آرایه‌ها می‌توانند مقادیری با «نوع داده» (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 پایتون

قطعه کد زیر، نمونه‌ای از مقایسه دو لیست در پایتون را با استفاده از تابع 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  ترتیب قرارگیری آیتم‌های درون مجموعه در نظر گرفته نمی‌شود و می‌توان صرفاً مقادیر درون مجموعه را با یکدیگر مقایسه کرد.

ساختار داده 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 پرداخته شد. همچنین، توضیحات مربوط به توابع پایتون برای مقایسه لیست‌ها و نحوه کار با آن‌ها در قالب مثال ارائه شدند.

بر اساس رای ۰ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
tutorialspointrealpythontowardsdatasciencejournaldevmiguendesfinxterdelftstack
۱ دیدگاه برای «مقایسه لیست ها در پایتون — راهنمای به زبان ساده»

سلام وقت بخیر ممنون بابت توضیحات کامل و جامع عالی بود👏🏼 یه سوالی دارم: اگر بخوایم دو تا لیست که رشته ای هستند رو با هم مقایسه کنیم و مقادیر لیست کوچک تر رو از لیست بزرگتر حذف کنیم…چطوری میشه اینکا رو کرد؟

نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *