برنامه‌نویسی پایتون فهرست مطالب
فصل ۹

لیست‌ها

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

در این فصل می‌خوانید
  1. ساختن لیست
  2. اندیس و برش
  3. لیست تغییرپذیر است
  4. اضافه کردن عضو
  5. حذف کردن عضو
  6. جست‌وجو در لیست
  7. پیمایش لیست
  8. ساختن لیست از ورودی کاربر
  9. برنامه: میانگین طول نام‌ها
  10. لیست به عنوان پشته و صف
  11. دام کپی کردن لیست

۱. ساختن لیست

لیست مجموعه‌ای مرتب از مقدارهاست که داخل کروشه نوشته می‌شوند و با ویرگول از هم جدا می‌شوند.

# A list holds several values in one variable, in a fixed order,
# written between square brackets and separated by commas.
animals = ['Cat', 'Lion', 'Dog', 'Wolf']
numbers = [5, 7, 15, 32, 104, 1]
empty = []                         # a list with nothing in it

print(animals)
print(numbers)
print(empty)

print(animals[0])                  # the first item
print(type(animals))               # <class 'list'>
print(len(animals))                # how many items -> 4

# A list may even mix different types (rarely a good idea, but it is allowed).
mixed = ['Ali', 20, 19.5, True]
print(mixed)

ساختن لیست: نمونه 01_create_list.py

['Cat', 'Lion', 'Dog', 'Wolf']
[5, 7, 15, 32, 104, 1]
[]
Cat
<class 'list'>
4
['Ali', 20, 19.5, True]

شرح مثال

۲. اندیس و برش

همه چیزهایی که در فصل سوم درباره اندیس و برش رشته یاد گرفتید، عیناً برای لیست هم صادق است.

# Indexes and slices work exactly like they do on strings.
cars = ['BMW', 'Benz', 'Pride', 'Paykan', 'Ford']

print(cars[0])      # 'BMW'
print(cars[-1])     # 'Ford'   -> the last one
print(cars[1:3])    # ['Benz', 'Pride']
print(cars[:2])     # ['BMW', 'Benz']
print(cars[2:])     # ['Pride', 'Paykan', 'Ford']
print(cars[::-1])   # the list reversed

اندیس و برش لیست: نمونه 02_indexing_slicing.py

دقت کنید که cars[0] یک رشته می‌دهد ولی cars[1:3] یک لیست. اندیس یک عضو می‌دهد، برش همیشه لیست می‌دهد، حتی اگر فقط یک عضو داشته باشد.

۳. لیست تغییرپذیر است

این مهم‌ترین تفاوت لیست با رشته است. رشته را نمی‌شد عوض کرد، لیست را می‌شود.

# A list is MUTABLE: an item can be replaced without creating a new list.
cars = ['BMW', 'Benz', 'Pride']

cars[2] = 'Peugeot'
print(cars)             # ['BMW', 'Benz', 'Peugeot']

# A whole slice can be replaced as well.
cars[0:2] = ['Mazda', 'Kia']
print(cars)

# Remember: a string cannot be changed like this,
#   name = 'kadoos'
#   name[0] = 'K'      ->  TypeError

تغییرپذیری: نمونه 03_mutable.py

رشتهلیست
تغییر یک عضوممکن نیستممکن است
متدهارشته تازه برمی‌گردانندخود لیست را عوض می‌کنند
نمونهs = s.upper()lst.append(x)

این تفاوت را خوب به خاطر بسپارید: متدهای لیست معمولاً چیزی برنمی‌گردانند و مستقیم خود لیست را عوض می‌کنند. نوشتن numbers = numbers.append(5) یک اشتباه رایج است که مقدار None را در متغیر می‌ریزد و لیست را از دست می‌دهید.

۴. اضافه کردن عضو

numbers = [10, 20, 30]

# append() adds ONE item at the end.
numbers.append(40)
print(numbers)          # [10, 20, 30, 40]

# insert() adds an item at a chosen position.
numbers.insert(0, 5)
print(numbers)          # [5, 10, 20, 30, 40]

# extend() adds all the items of another list.
numbers.extend([50, 60])
print(numbers)          # [5, 10, 20, 30, 40, 50, 60]

# Careful: append() with a list adds the LIST itself as one single item.
numbers.append([70, 80])
print(numbers)          # [..., 60, [70, 80]]

# '+' builds a new list without touching the originals.
print([1, 2] + [3, 4])

اضافه کردن: نمونه 04_add_items.py

متدوظیفه آن
append(x)یک عضو به انتها اضافه می‌کند
insert(i, x)یک عضو در جای مشخص جا می‌دهد
extend(lst)همه اعضای یک لیست دیگر را اضافه می‌کند
+لیست تازه می‌سازد، اصلی‌ها دست‌نخورده می‌مانند
فرق append و extend

append([70, 80]) کل لیست را به عنوان یک عضو اضافه می‌کند، پس لیستی تودرتو می‌سازید. extend([70, 80]) اعضایش را یکی‌یکی اضافه می‌کند. هر دو مجازند و هر کدام کاربرد خودش را دارد، ولی قاطی کردنشان باگ‌های عجیب می‌سازد.

۵. حذف کردن عضو

numbers = [5, 20, -7, 8, 14]

# pop() removes an item BY POSITION and returns it.
last = numbers.pop()        # no argument -> the last item
print('Removed:', last, '->', numbers)

first = numbers.pop(0)      # by index
print('Removed:', first, '->', numbers)

# remove() removes the first item equal to the given VALUE.
numbers.remove(8)
print(numbers)

# del removes by index (or by slice) without returning anything.
del numbers[0]
print(numbers)

# clear() empties the list.
numbers.clear()
print(numbers)              # []

حذف کردن: نمونه 05_remove_items.py

روشبر اساسمقدار برمی‌گرداند
pop()جایگاه، پیش‌فرض آخریبله
remove(x)مقدار، اولین تطابقخیر
del lst[i]جایگاه یا برشخیر
clear()همه چیزخیر

اگر remove مقداری را پیدا نکند، خطای ValueError می‌دهد. پس پیش از حذف، با in بررسی کنید که واقعاً وجود دارد.

۶. جست‌وجو در لیست

cars = ['BMW', 'Benz', 'Pride', 'Paykan', 'Ford', 'Benz']

car = input('Enter the car name: ')

# 'in' tells us whether a value exists in the list.
if car in cars:
    print(car, 'found.')
else:
    print(car, 'not found!')

# index() gives the position of the FIRST occurrence.
print(cars.index('Pride'))

# count() says how many times a value appears.
print(cars.count('Benz'))    # 2

جست‌وجو: نمونه 06_search_in_list.py

سه ابزار جست‌وجو: in برای «هست یا نیست»، index برای «کجاست» و count برای «چند تا». مثل remove، اگر index چیزی پیدا نکند خطا ایجاد می‌کند، پس معمولاً اول با in بررسی می‌کنند.

۷. پیمایش لیست

numbers = [200, 350, 40, 1000, 270]

# Way 1 (the usual one): loop directly over the items.
for number in numbers:
    print(number, end=' ')
print()

# Way 2: loop over the indexes. Useful when we also need the position,
# or when we want to CHANGE the items.
for i in range(len(numbers)):
    print(f'index {i} -> {numbers[i]}')

# Changing every item needs the index version.
for i in range(len(numbers)):
    numbers[i] = numbers[i] * 2

print(numbers)

دو روش پیمایش: نمونه 07_loop_over_list.py

شرح مثال

۸. ساختن لیست از ورودی کاربر

# Starting from an empty list and filling it with append().
numbers = []

while True:
    user_input = input('Enter a number (or "exit"): ')

    if user_input == 'exit':
        break

    numbers.append(float(user_input))

print('You entered:', numbers)
print('How many:', len(numbers))

if len(numbers) > 0:
    total = 0
    for number in numbers:
        total += number
    print('Average:', total / len(numbers))

پر کردن لیست: نمونه 08_build_from_input.py

اینجا سه چیزی که تا حالا یاد گرفته‌اید کنار هم آمده‌اند: حلقه نگهبان از فصل هشتم، الگوی انباره از فصل ششم و لیست از این فصل. تقریباً همه برنامه‌های واقعی همین شکل را دارند: جمع کن، بعد پردازش کن.

۹. برنامه: میانگین طول نام‌ها

# Reading names into a list and computing the average length of the names.
names = []

while True:
    user_input = input('Enter a name (or "exit"): ')

    if user_input == 'exit':
        break

    names.append(user_input)

if len(names) == 0:
    print('No name was entered.')
else:
    total = 0
    for name in names:
        total += len(name)

    print('Average length of the names:', total / len(names))

میانگین طول نام‌ها: نمونه 09_names_length.py

باز هم بررسی لیست خالی پیش از تقسیم. این را به عادت تبدیل کنید: هر جا len(...) در مخرج یک تقسیم است، حالت صفر را جدا بررسی کنید.

۱۰. لیست به عنوان پشته و صف

پشته ساختاری است که «آخرین ورودی، اولین خروجی» است. درست مثل دسته بشقاب: بشقابی که آخر گذاشته‌اید، اول برداشته می‌شود.

# A stack is a "last in, first out" container.
# A Python list is already a perfect stack: append() to push, pop() to pop.
my_stack = []

my_stack.append(5)
my_stack.append(20)
my_stack.append(-7)
print(my_stack)          # [5, 20, -7]

item = my_stack.pop()    # takes the LAST item
print('Popped:', item)   # -7
print(my_stack)          # [5, 20]

my_stack.pop()
print(my_stack)          # [5]

# By popping index 0 instead, the list behaves as a queue (first in, first out).
queue = [5, 20, -7, 8, 14]
queue.pop(0)
queue.pop(0)
print(queue)             # [-7, 8, 14]

پشته و صف: نمونه 10_stack.py

شرح مثال

۱۱. دام کپی کردن لیست

این بخش را با دقت بخوانید. یکی از گیج‌کننده‌ترین رفتارهای پایتون برای تازه‌کارها همین است.

# IMPORTANT TRAP: '=' does not copy a list, it only gives it a second name.
list1 = [1, 2, 3]
list2 = list1

list2.append(4)
print(list1)      # [1, 2, 3, 4]  -> list1 changed too!

# To get a real copy use copy(), list() or a full slice.
list3 = list1.copy()
list3.append(5)
print(list1)      # [1, 2, 3, 4]  -> unchanged
print(list3)      # [1, 2, 3, 4, 5]

list4 = list1[:]     # the same idea with a slice
print(list4)

دام کپی: نمونه 11_copy_list.py

شرح مثال

همین دام در جای دیگری هم هست

وقتی لیستی را به یک تابع بدهید، تابع همان لیست را می‌گیرد، نه کپی‌اش را. اگر تابع تغییرش دهد، لیست اصلی شما هم عوض می‌شود. در فصل دوازدهم دقیقاً روی همین موضوع مکث می‌کنیم.

فایل‌های تمرینی این فصل

پوشه S09-lists شامل نمونه‌های 01_create_list.py تا 11_copy_list.py.

خلاصه فصل

ابزاروظیفه آن
[a, b, c]ساختن لیست. [] یعنی لیست خالی
lst[i] و lst[a:b]اندیس و برش، دقیقاً مثل رشته
lst[i] = xتغییر یک عضو. رشته این را ندارد
append insert extendاضافه کردن
pop remove del clearحذف کردن
in index count lenجست‌وجو و شمارش
for x in lstپیمایش مقدارها
for i in range(len(lst))پیمایش اندیس‌ها، برای تغییر دادن
پشته و صفappend با pop() یا با pop(0)
lst2 = lst1کپی نیست. برای کپی: copy() یا [:]

تمرین‌های فصل نه

  1. لیستی از پنج شهر بسازید و هر کدام را در یک خط چاپ کنید.
  2. پنج عدد در یک لیست بگیرید و لیست را برعکس چاپ کنید.
  3. لیستی از نام‌ها بگیرید و فقط آنهایی که با A شروع می‌شوند را چاپ کنید.
  4. عدد بگیرید تا exit، و بگویید چند تایشان زوج بودند.
  5. عضوهای تکراری یک لیست را حذف کنید، بدون استفاده از set که هنوز نخوانده‌ایم.
  6. لیستی از اعداد بگیرید و لیست دومی بسازید که فقط اعداد مثبت را دارد.
  7. یک جمله بگیرید، با split() به کلمات بشکنیدش و بلندترین کلمه را چاپ کنید.
  8. یک برنامه «فهرست خرید» با منو بنویسید: افزودن کالا، حذف کالا، نمایش فهرست و خروج.
فصل قبل: حلقه while فصل بعد: الگوریتم‌های لیست