آموزش پایتون کلید ورود به دنیای هوش مصنوعی (گام دوم - قسمت پانزدهم: لیست ها - بخش دوم)

سلام رفقا

در قسمت قبل از آموزش پایتون به عنوان کلید ورود به دنیای هوش مصنوعی در مورد لیست ها که به عنوان پر استفاده ترین ابزار در پایتون هستند صحبت کردیم در این قسمت هم این موضوع رو ادامه میدیم. اگر اولین باره این مطلب رو می خونید و دوست دارید پایتون یاد بگیرید به جلسه اول آموزش پایتون در این لینک برید و شروع کنید. برای اینکه بتونم جامع ترین آموزش رایگان پایتون رو در وب فارسی بنویسم نیاز به حمایت تک تک شما عزیزان دارم. با معرفی به دوستانتون می تونید در زمینه بهم یاری برسونید.

ما الان اینجا هستیم :


دسترسی به مقادیر لیست

همونطور که گفتیم اندیس در پایتون از صفر شروع میشه. برای دسترسی به مقادیر لیست میتونیم از شماره ایندکس هر مقدار استفاده کنیم. مثلا اندیس صفرم نشون دهنده مقدار اول هست که اینجا 1 هست:

1234lst = [1, 2, 3, 4]
lst[ 0 ]    # 1
lst[ 1 ]    # 2

اگه از اندیسی استفاده کنیم که تو لیست نیست، IndexError میده. الان در مثال بالا ما اندیس های 0و1و2و3 رو داریم پس وقتی 4 رو بخوایم ارور می ده می گه نیست :

12lst[ 4 ]          # IndexError: list index out of range

اندیس گذاری منفی هم که از آخر شروع میکنیم، اندیس آیتم آخر 1- ، قبلی 2- تا برسه به اولین آیتم:

1234lst[ -1 ]    # 4
lst[ -2 ]    # 3
lst[ -5 ]    # IndexError: list index out of range

مثلا شکل زیر رو نگاه کنید. از صفر شروع می شه میره جلو و از منفی بر می گرده عقب :

لیست به ما این اجازه رو میده که از برش [start:end:step] استفاده کنیم. خروجی این برش یک لیست جدید هست که از اندیس start شروع میشه به اندیس end ختم میشه. step هم میگه که چجوری گام برداریم. با چند تا مثال بهتون توضیح میدم:

12345678lst[1:]              # [2, 3, 4]
lst[:3]              # [1, 2, 3]
lst[::2]             # [1, 3]
lst[::-1]            # [4, 3, 2, 1]
lst[-1:0:-1]       # [4, 3, 2]
lst[5:8]            # [ ] since starting index is greater than length of lst, returns empty list
lst[1:10]          # [2, 3, 4] same as omitting ending index

تو مثال اول اندیس شروع 1 هست و اندیس پایان و step رو نداریم، پس لیست جدید از اندیس 1 شروع میشه تا آخر. تو مثال دوم اندیس شروع و step رو نداریم، لیست جدید از اندیس 0 شروع میشه تا اندیس 3 ولی مقدار خود اندیس 3 تو لیست جدید نباید باشه. تو مثال سوم فقط step رو داریم، لیست جدید از اندیس 0 شروع میشه و دوتا دوتا میره جلو تا آخر. مثال بعدی stepمون 1- هست، یعنی معکوس میکنه لیست رو. مثال بعدی اندیس شروع 1- هست و اندیس پایان 0 و step هم که 1- ، واضحه دیگه. مثال بعدی اندیس شروع 5 هست و اندیس پایان 8، لیست جدید خالیه چون که اندیس هایی که برش بهمون داده بیشتر از طول لیسته. مثال آخر اندیس شروع 1 هست و اندیس پایان 10، اندیس 10 که نداریم پس از اندیس 1 شروع میشه تا آخر.

یه مثال دیگه:

12lst[3:1:-1]      # [4, 3]

وقتی step منفی باشه باید اندیس شروع بیشتر از اندیس پایان باشه.

وقتی از step منفی استفاده می کنیم انگار از تابع reversed که واسه معکوس کردن عناصر لیست هست و پایین توضیح میدیم، استفاده کردیم:

123reversed(lst)[0:2]      # 0 = 1 -1
                                  # 2 = 3 -1

چجوری چک کنیم که لیست خالی هست؟

تو پایتون خالی بودن لیست با boolean False همراه هست. از این رو عبارت شرطی زیر رو می تونیم برای بررسی خالی بودن لیست استفاده کنیم:

12345lst = [ ]
if not lst :
         print(&quotlist is empty&quot)
# Output: list is empty

یا:

123if len(lst) == 0 :
         print(&quotlist is empty&quot)

پیمایش روی یک لیست

ما می تونیم از حلقه for مستقیما تو یک لیست استفاده کنیم(اینجا راجب حلقه های توضیح دادم). الان هر کدوم از عضوهای لیست چاپ شدن:

1234567my_list = ['foo', 'bar', 'baz']
for item in my_list:
       print(item)
# Output: foo
# Output: bar
# Output: baz

روش دیگۀ پیمایش لیست براساس مقدار اندیس هست یعنی می گه اگر اندیس ما توی رنج 0 تا طول لیستمون بود دستور پرینت رو انجام بده:

12345678for i in range(0 , len(my_list)) :
      print(my_list[i])
#output :
>>>
foo
bar
baz

تو پرانتز جلوی range اولین مورد اندیس شروعه پیمایش هست که اینجا صفره، دومین مورد هم طول پیمایشِ که اینجا کل لیست هست یعنی از اول تا کل طول لیست.

توجه کنید که تغییر آیتم ها در یک لیست وقتی که داریم روی لیست پیمایش انجام میدیم، ممکنه نتایج غیر منتظره ای داشته باشه:

1234567for item in my_list :
       if item == 'foo' :
              del my_list[0]
       print(item)
# Output :  foo
# Output :  baz

تو مثال بالا، اولین آیتم رو تو پیمایش حذف کردیم، اما این باعث پرش شد.

چجوری چک کنیم یک آیتم تو لیست هست

خیلی راحت می تونیم این کارو انجام بدیم با کلمه in:

1234567lst = ['test', 'twest', 'tweast', 'treast']
'test' in lst
# Out: True

'toast' in lst
# Out: False

همونظور که می بینید اگه آیتم بود که true و اگه نبود false رو برمی گردونه.

البته اگه ما این کارو روی یک مجموعه انجام بدیم، خیلی سریع تره. پس می تونیم وقتایی که لیست خیلی بزرگ بود واسه سرعت بخشیدن به کارمون اول لیست رو به مجموعه تبدیل کنیم و بعد چک کنیم ببینیم آیتم مورد نظرمون هست یا نه:

1234slst = set(lst)
'test' in slst
# Out: True

دستور Any و All

حالا می خوام راجع به تابع های ( )all و ( )any توضیح بدم:

تابع any: اگه همه مقادیر false باشند یا لیست خالی باشه، false برمی گردونه. اگه همه مقادیرمون true یا حداقل یکی از مقادیرمون true باشه، true برمی گردونه:

1234567891011121314nums = [1, 1, 0, 1]
any(nums)
# True

vals = [None, None, None, False]
any(vals)
# False

vals = [1, 2, 3, 4]
any(val > 12 for val in vals)
# False
any((val * 2) > 6 for val in vals)
# True

تابع all: اگه همه مقادیر true باشند یا لیست خالی باشه، true برمی گردونه. اگه همه مقادیرمون false یا حداقل یکی از مقادیرمون false باشه، false برمی گردونه:

12345678nums = [1, 1, 0, 1]
all(nums)
# False

chars = ['a', 'b', 'c', 'd']
all(chars)
# True

معکوس کردن عنصرهای لیست

شما می تونید از تابع reversed واسه معکوس کردن عنصرهای یک لیست استفاده کنید:

1234567numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]

In [3]: rev = reversed(numbers)

In [4]: rev
Out[4]: [9, 8, 7, 6, 5, 4, 3, 2, 1]

همونطور که تو متدها توضیح دادم، برای معکوس کردن عناصر می تونیم از متد ( )reverse هم استفاده کنیم. یا می تونیم از step منفی که تو قسمت دسترسی به مقادیر توضیح دادم، استفاده کنید:

12345In [1]: numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]

In [2]: numbers[::-1]
Out[2]: [9, 8, 7, 6, 5, 4, 3, 2, 1]

جمع کردن و ادغام لیست ها

یک راه ساده واسه جمع کردن list1 و list2 استفاده از + است:

12merged = list1 + list2

وقتی می خوایم یک لیست از تاپل ها داشته باشیم، از zip استفاده می کنیم:

12345678910alist = ['a1', 'a2', 'a3']
blist = ['b1', 'b2', 'b3']

for a, b in zip(alist, blist):
       print(a, b)
# Output:
# a1 b1
# a2 b2
# a3 b3

اگه لیست ها طول متفاوتی داشته باشن، به اندازه لیست کوتاه تر رو شامل میشه یعنی اینجا کوتاهترین لیست 3 تا عضو داره بنابراین خروجی هم سه تا میشه:

123456789101112131415alist = ['a1', 'a2', 'a3']
blist = ['b1', 'b2', 'b3', 'b4']

for a, b in zip(alist, blist):
       print(a, b)
# Output:
# a1 b1
# a2 b2
# a3 b3

alist = [ ]
len(list(zip(alist, blist)))
# Output:
# 0

اگه می خوایم به اندازه طول لیست بزرگتر باشه، از itertools.zip_longest استفاده می کنیم:

123456789101112alist = ['a1', 'a2', 'a3']
blist = ['b1']
clist = ['c1', 'c2', 'c3', 'c4']

for a,b,c in itertools.zip_longest(alist, blist, clist):
       print(a, b, c)
# Output:
# a1 b1 c1
# a2 None c2
# a3 None c3
# None None c4

به جای بقیه عناصر لیست های کوتاه تر None میذاره.

از متد (insert(index, value استفاده کنیم:

1234alist = [123, 'xyz', 'zara', 'abc']
alist.insert(3, [2009])
      print(&quotFinal List :&quot, alist)

Output:

12Final List : [123, 'xyz', 'zara', 2009, 'abc']

طول یک لیست

از ( )len برای به دست آوردن طول لیست استفاده می کنیم:

123len(['one', 'two'])                 # returns 2
len(['one', [2, 3], 'four'])       # returns 3, not 4

تو دومیه خروجی 3 میشه نه 4، چون [3 ,2] یک عنصر هست نه دوتا.

توجه کنید که ( )len یک تابع توکار هست نه متد.

حذف مقادیر تکراری در لیست

برای حذف مقادیر تکراری در لیست می تونیم لیست رو به مجموعه تبدیل کنیم. همونطور که تو مجموعه ها گفتیم نمی تونیم عنصر تکراری در مجموعه ذخیره کنیم. بعد اگه به ساختار داده لیست نیاز داشتیم دوباره مجموعه رو به لیست تبدیل کنیم با استفاده از تابع ( )list:

1234names = [&quotaixk&quot, &quotduke&quot, &quotedik&quot, &quottofp&quot, &quotduke&quot]
list(set(names))
# Out: ['duke', 'tofp', 'aixk', 'edik']

توجه داشته باشید که با تبدیل یک لیست به یک مجموعه ، ترتیب اصلی از بین می رود. برای حفظ ترتیب لیست می تونید از OrderedDict استفاده کنید:

1234import collections
>>> collections.OrderedDict.fromkeys(names).keys()
# Out: ['aixk', 'duke', 'edik', 'tofp']

مقایسه لیست ها

برای مقایسه لیست ها از عملگرهای مقایسه استفاده می کنیم. برای این کار هر دو عملوند باید از یک نوع باشند. از اول شروع می کنه یکی یکی مقایسه کردن و اگر نتیجه مطلوبی نداشته باشه همونجا false برمیگردونه:

1234567891011[1, 10, 100] < [2, 10, 100]
# True, because 1 < 2
[1, 10, 100] < [1, 10, 100]
# False, because the lists are equal
[1, 10, 100] <= [1, 10, 100]
# True, because the lists are equal
[1, 10, 100] < [1, 10, 101]
# True, because 100 < 101
[1, 10, 100] < [0, 10, 100]
# False, because 0 < 1

اگه شروع دوتا لیست یکی باشه، لیست کوتاه تر کمتره:

123[1, 10] < [1, 10, 100]
# True

دسترسی به مقادیر لیست تو در تو

با یک لیست سه بعدی شروع می کنیم:

alist = [ [ [1,2],[3,4] ], [ [5,6,7],[8,9,10], [12, 13, 14] ] ]

123print(alist [0] [0] [1])
#2

دومین عنصر در لیست اولِ لیست اول.

123print(alist[1] [1] [2])
#10

سومین عنصر در لیست دومِ لیست دوم.

1234alist[0] [0].append(11)
print(alist[0] [0] [2])
#11

تو مثال بالا به انتهای اولین لیستِ لیست اول مقدار 11 رو append کردیم.

می تونیم از حلقه های for تو در تو برای print لیست استفاده کنیم:

123456789for row in alist:         #One way to loop through nested lists
       for col in row:
              print(col)
#[1, 2, 11]
#[3, 4]
#[5, 6, 7]
#[8, 9, 10]
#[12, 13, 14]

توجه داشته باشید که کد بالا رو با استفاده از خلاصه لیست می تونیم به شکل زیر بنویسیم(خلاصه لیست رو تو بخش بعدی مفصل توضیح میدیم و لینکشو همین جا میذاریم):

123[col for row in alist for col in row]
#[ [1, 2, 11], [3, 4], [5, 6, 7], [8, 9, 10], [12, 13, 14] ]

یک راه دیگه برای استفاده از حلقه های for تو در تو:

12345678910for row in range(len(alist)): 
       for col in range(len(alist[row])):
              print(alist[row][col])
#[1, 2, 11]
#[3, 4]
#[5, 6, 7]
#[8, 9, 10]
#15
#[12, 13, 14]

استفاده از برش در لیست تو در تو:

123print(alist[1] [1:])
#[ [8, 9, 10], 15, [12, 13, 14] ]

مثال بالا میگه که لیست با اندیس 1 که میشه لیست دومِ این لیست:

alist = [[[1, 2, 11], [3, 4]], [[5, 6, 7], [8, 9, 10], 15, [12, 13, 14]]]

از اندیس 1 که میشه دومین عنصر شروع بشه تا آخرین اندیس لیست دوم.

ضرب یک لیست در یک عدد ثابت

برای عناصر immutable (تغییر ناپذیر):

123my_list = [None] * 10
my_list = ['test'] * 10

برای عناصر mutable (تغییر پذیر) ، برای مثال یک مجموعه:

1234567>>> my_list=[{1}] * 10
>>> print(my_list)
[{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}]
>>> my_list[0].add(2)
>>> print(my_list)
[{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}]

اگه سوالی داشتید کامنت کنید