۳۰ شهریور ۱۴۰۳

Techboy

اخبار و اطلاعات روز تکنولوژی

نحوه کار با نوع داده لیست پایتون

از لیست‌های پایتون برای ذخیره داده‌ها در ردیف‌های یک‌بعدی، دسترسی به آن‌ها بر اساس شاخص‌ها و مرتب‌سازی آن‌ها به هر شکلی که دوست دارید استفاده کنید.

از لیست‌های پایتون برای ذخیره داده‌ها در ردیف‌های یک‌بعدی، دسترسی به آن‌ها بر اساس شاخص‌ها و مرتب‌سازی آن‌ها به هر شکلی که دوست دارید استفاده کنید.

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

مبانی لیست پایتون

تعریف لیست در پایتون آسان است—فقط از سینتکس براکت برای نشان دادن موارد موجود در لیست استفاده کنید، مانند این:


list_of_ints = [1, 2, 3]

موارد موجود در لیست لازم نیست همه یک نوع باشند. آنها می توانند هر شی پایتون باشند. در لیست زیر، فرض کنید Three یک تابع است:


list_of_objects = ["One", TWO, Three, {"Four":4}, None]

توجه داشته باشید که وجود اشیاء ترکیبی در یک لیست می تواند پیامدهایی برای مرتب سازی لیست داشته باشد. بعداً به آن خواهیم پرداخت.

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

در مثال list_of_ints، list_of_ints[0] ۱، list_of_ints[1] ۲ و list_of_objects[4] شیء هیچکدام  خواهند بود.

نمایه سازی لیست پایتون

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

در این صورت، list_of_ints[-1]  ۳ و list_of_objects[-1]  هیچکد.

شما همچنین می توانید از یک متغیر عدد صحیح به عنوان شاخص خود استفاده کنید. اگر  x=0، list_of_ints[x] به‌دست می‌آید ۱ و غیره.

اگر بخواهید فراتر از مرزهای فهرست فهرست بندی کنید، یک استثنا IndexError را راه اندازی خواهید کرد.

افزودن و حذف موارد لیست پایتون

Python چندین راه برای اضافه کردن یا حذف موارد از یک لیست دارد:

  • .append() یک مورد را در انتها لیست درج می‌کند. برای مثال، list_of_ints.append(4) list_of_ints را به فهرست [۱،۲،۳،۴] تبدیل می‌کند. ضمیمه ها سریع و کارآمد هستند. صرف نظر از اینکه لیست چقدر طولانی باشد، تقریباً به همان مقدار زمان نیاز است تا یک مورد به فهرست اضافه شود.
  • .extend() محتویات برخی از تکرارپذیرها را می گیرد – مانند لیستی دیگر – و هر مورد را از تکرارپذیر به عنوان یک آیتم جداگانه به لیست اضافه می کند. اگر بخواهید به سرعت محتویات یک لیست را مورد به مورد در لیست دیگری وارد کنید، مفید است. (اگر سعی کنید .append() یک لیست را به لیست دیگر اضافه کنید، کل لیست به جای آیتم به مورد، به عنوان یک شی منفرد اضافه می شود.)
  • .pop() آخرین مورد را از لیست حذف و برمی‌گرداند. اگر x = list_of_ints.pop() را در list_of_ints اصلی اجرا کنیم، x حاوی مقدار ۳ خواهد بود. (اگر به آن نیاز ندارید، لازم نیست نتایج .pop()  را به مقداری اختصاص دهید.) .pop()عملیات نیز سریع هستند و کارآمد.
  • .insert() یک مورد را در یک موقعیت دلخواه در لیست درج می کند. برای مثال، list_of_ints.insert(0,10) list_of_ints را به [۱۰,۱,۲,۳] تبدیل می‌کند. توجه داشته باشید که هرچه به قسمت جلوی لیست نزدیک‌تر شوید، این عملیات کندتر خواهد بود، اگرچه کاهش سرعت زیادی را مشاهده نخواهید کرد مگر اینکه لیست شما دارای هزاران عنصر باشد یا درج‌ها را در یک حلقه محکم انجام دهید.
  • .pop(x) مورد را در فهرست x حذف می‌کند. بنابراین  list_of_ints.pop(0) مورد را در نمایه ۰ حذف می‌کند. باز هم، هرچه به جلوی لیست نزدیک‌تر باشید، این عملیات کندتر می‌شود.
  • .remove(item) یک مورد را از فهرست حذف می‌کند، اما نه بر اساس نمایه آن. در عوض، .remove()  اولین رخداد ابجایی را که مشخص کرده‌اید حذف می‌کند و از بالای فهرست به پایین جستجو می‌کند. برای [۳,۷,۷,۹,۸].remove(7)، اولین ۷ حذف می‌شود و در نتیجه فهرست [۳،۷ ایجاد می‌شود. ,۹,۸]. این عملیات نیز می تواند برای یک لیست بزرگ کند شود، زیرا از نظر تئوری باید کل لیست را طی کند تا کار کند.

بریدن لیست پایتون

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

در بالا دیدید که چگونه می توان از نماد براکت برای دریافت یک مورد از یک لیست استفاده کرد: برای مثال my_list[2]. برش ها از یک نوع نماد شاخص استفاده می کنند (و از قوانین نمایه سازی یکسانی پیروی می کنند): list_object[start:stop:step].

به موارد زیر توجه کنید:

  • ستارهt موقعیت شروع برش در لیست است.
  • توقف موقعیتی در لیست است که در آن برش را متوقف می‌کنیم. به عبارت دیگر، آن موقعیت و همه چیز بعد از آن حذف شده است.
  • step یک نشانگر اختیاری “هر نهمین عنصر” برای برش است. به‌طور پیش‌فرض، این ۱ است، بنابراین برش تمام عناصر فهرستی را که از آن جدا می‌شود، حفظ می‌کند. step را روی ۲ تنظیم کنید و هر عنصر دوم و غیره را انتخاب کنید.

در اینجا چند نمونه آورده شده است. این لیست را در نظر بگیرید:


slice_list = [1,2,3,4,5,6,7,8,9,0]
slice_list[0:5] = [1, 2, 3, 4, 5]

توجه داشته باشید که ما در نمایه ۴ متوقف می شویم، نه در نمایه ۵!


slice_list[0:5:2] = [1, 3, 5]

اگر یک شاخص برش خاصی را حذف کنید، پایتون یک پیش فرض را در نظر می گیرد. ایندکس start را کنار بگذارید و پایتون شروع لیست را فرض می کند:


slice_list[:5] = [1, 2, 3, 4, 5]

شاخص stop را کنار بگذارید و پایتون انتهای لیست را فرض می‌کند:


slice_list[4:] = [5, 6, 7, 8, 9, 0]

عنصر step هم می‌تواند منفی باشد. این به ما امکان می‌دهد برش‌هایی بگیریم که کپی‌های معکوس از نسخه اصلی هستند:


slice_list[::-1] = [0, 9, 8, 7, 6, 5, 4, 3, 2, 1]

توجه داشته باشید که می‌توانید با استفاده از نمایه‌های start و stop که به عقب و نه جلو حرکت می‌کنند، برعکس آن را برش دهید:


slice_list[5:2:-1] = [6, 5, 4]

نسخه های برش و کم عمق

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

به عنوان مثال، اگر یک نمونه کلاس در یک لیست داشته باشید و یک برش حاوی آن شی بسازید، یک نمونه کلاس جدید مجزا ایجاد نمی‌شود—این برش اکنون حاوی یک مرجع متفاوت به نمونه کلاس همان.

برش و نمایه های خارج از محدوده

اگر سعی کنید تکه‌ای بزرگ‌تر از موردی که برش می‌دهید ایجاد کنید – یک برش “خارج از محدوده” – IndexError دریافت نمی‌کنید، اما فقط به همان اندازه دریافت خواهید کرد مورد برش خورده در واقع دارد. به عنوان مثال:

[۱,۲,۳][:۱۰]

[۱,۲,۳] را ایجاد می کند. این به شما امکان می‌دهد بدون نگرانی بیش از حد در مورد محدود کردن مرزهای برش به چیزی که برش می‌دهید، برش‌هایی درست کنید.

مرتب‌سازی فهرست پایتون

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

برای ایجاد یک لیست مرتب شده جدید، از تابع sorted() در لیست قدیمی استفاده کنید:


new_list = sorted(old_list)

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

اگر می‌خواهید فهرستی را به صورت معکوس مرتب کنید، پارامتر reverse را ارسال کنید:


new_list = sorted(old_list, reverse=True)

روش دیگر برای مرتب‌سازی، مرتب‌سازی درجا، عملیات مرتب‌سازی را مستقیماً در فهرست اصلی انجام می‌دهد. برای انجام این کار، از روش  .sort()در فهرست استفاده کنید:


old_list.sort()

.sort() همچنین reverse را به‌عنوان پارامتر می‌گیرد و به شما امکان مرتب‌سازی معکوس را می‌دهد.

توجه داشته باشید که محتویات لیست باید یکسان باشد تا مرتب سازی کار کند. برای مثال، نمی‌توانید ترکیبی از اعداد صحیح و رشته‌ها را مرتب کنید، اما می‌توانید فهرستی را که همه اعداد صحیح یا تمام رشته‌ها باشد مرتب کنید. در غیر این صورت یک TypeError در عملیات مرتب‌سازی دریافت خواهید کرد.

هر دو sorted() و .sort() همچنین یک پارامتر key  را می گیرند. پارامتر key به شما امکان می دهد تابعی را ارائه دهید که می تواند برای انجام یک عملیات مرتب سازی سفارشی استفاده شود. وقتی فهرست مرتب شد، هر عنصر به تابع key  منتقل می‌شود و مقدار حاصل برای مرتب‌سازی استفاده می‌شود. برای مثال، اگر ترکیبی از اعداد صحیح و رشته‌ها داشته باشیم و بخواهیم آنها را مرتب کنیم، می‌توانیم از key استفاده کنیم، مانند این:


mixed_list = [1,"2",3,"4", None]

def sort_mixed(item):
    try:
        return int(item)
    except ValueError:
        return 0

sorted_list = sorted(mixed_list, key = sort_mixed)
print (sorted_list)

توجه داشته باشید که این کد هر عنصر لیست را به یک عدد صحیح تبدیل نمی‌کند! در عوض، از عدد صحیح مقدار هر مورد به عنوان مقدار مرتب‌سازی آن استفاده می‌کند. همچنین توجه داشته باشید که چگونه از بلوک  try/except برای به دام انداختن مقادیری که به طور واضح به یک عدد صحیح ترجمه نمی‌شوند استفاده می‌کنیم و به‌طور پیش‌فرض ۰ را برای آن‌ها برمی‌گردانیم.

اشیاء فهرست چند بعدی

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

در اینجا یک مثال از یک لیست دو بعدی آمده است:


two_dimensional_list = [
    [۰,۱,۲],
[۳,۴,۵]
]

بیرونی ترین فهرست، بعد اول، دو عنصر است. بعد داخلی، لیست های درون، هر کدام سه عنصر هستند.

اگر می‌خواهید به لیست‌های داخل دسترسی داشته باشید، از یک نحو نمایه‌سازی انباشته شده مانند این استفاده می‌کنید:


two_dimensional_list[0][2]

با این کار اولین عنصر در لیست بیرونی – لیست [۰,۱,۲] – و سپس عنصر سوم از آن – ۲ به شما می‌دهد. .

توجه داشته باشید که پایتون هیچ نوع ابعادی را بر روی اشیایی مانند این اجباری نمی کند. می‌توانید فهرستی از فهرست‌ها داشته باشید که هر فهرست فرعی طولی کاملاً متفاوت دارد، اما باید مطمئن شوید که با استفاده از فهرست‌هایی که با شی مورد نظر مطابقت ندارند، IndexError ایجاد نکرده‌اید.

لیست های پایتون آرایه نیستند

یک نکته مهم که باید در مورد لیست ها در پایتون بدانید این است که آنها “آرایه” نیستند. زبان های دیگر، مانند C، ساختارهای یک بعدی یا چند بعدی به نام آرایه دارند که مقادیر یک نوع واحد را می پذیرند. فهرست ها ناهمگن هستند. آنها می توانند اشیاء از هر نوع را بپذیرند.

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

چه زمانی از لیست‌های پایتون استفاده کنیم (و چه زمانی استفاده نکنیم)

بنابراین، چه زمانی لیست‌های پایتون بیشترین کاربرد را دارند؟ فهرست زمانی بهترین است که:

  • شما باید به سرعت چیزها را بر اساس موقعیت آنها در یک مجموعه پیدا کنید. دسترسی به هر موقعیتی در یک لیست به همان میزان زمان نیاز دارد، بنابراین هیچ جریمه ای برای جستجوی حتی میلیونمین مورد در لیست وجود ندارد.
  • شما در حال افزودن و حذف به مجموعه عمدتاً با افزودن به انتها یا حذف از انتها، به روش پشته ای هستید. باز هم، این عملیات صرف نظر از طول لیست به همان مقدار زمان نیاز دارد.

لیست پایتون زمانی مناسب نیست:

  • شما می خواهید یک مورد را در لیست پیدا کنید اما موقعیت آن را نمی دانید. شما  می‌توانید این کار را با ویژگی .index()  انجام دهید. برای مثال، می‌توانید از list_of_ints.index(1) برای پیدا کردن نمایه اولین وقوع عدد ۱ در list_of_ints استفاده کنید. اگر لیست شما فقط چند آیتم طولانی دارد، سرعت نباید مشکلی ایجاد کند، اما برای لیست هایی که هزاران آیتم طولانی دارند، به این معنی است که پایتون باید کل لیست را جستجو کند. برای سناریویی مانند این، از یک فرهنگ لغت استفاده کنید، جایی که هر مورد را می توان با استفاده از یک کلید پیدا کرد، و زمان جستجو برای هر مقدار یکسان خواهد بود.
  • شما می‌خواهید مواردی را از هر موقعیتی به جز آخر اضافه یا حذف کنید. هر بار که این کار را انجام می‌دهید، پایتون باید هر آیتم دیگری را بعد از آیتم اضافه یا حذف شده منتقل کند. هرچه لیست طولانی تر باشد، مشکل عملکرد بیشتر می شود. اگر بخواهید آزادانه اشیاء را از ابتدا یا انتهای لیست اضافه یا حذف کنید، شیء deque پایتون مناسب‌تر است.