استفاده از حلقه در پایتون
حلقه for در پایتون برای اجرای مکرر یک بلوک کد استفاده می شود. حلقه های For بخش اساسی اکثر زبان های برنامه نویسی هستند. به خواندن ادامه دهید تا بدانید حلقه for در پایتون چگونه کار می کند و چگونه از آن استفاده کنید.
حلقه for در پایتون چیست؟
حلقه for یکی از شناخته شده ترین سازه های برنامه نویسی است. بیایید با استفاده از یک مثال عینی از زندگی روزمره به آن نگاه کنیم. بگو معلمی می خواهد میانگین قد دانش آموزانش را محاسبه کند. ابتدا از هر دانش آموز به نوبت می پرسد که قد آنها چقدر است و قد هر دانش آموز را به مجموع دویدن اضافه می کند. هنگامی که او این کار را برای هر دانش آموز انجام داد، کل را بر تعداد دانش آموزانی که در آنجا هستند تقسیم می کند تا میانگین قد دانش آموزانش را بدست آورد. ما می توانیم یک الگوریتم اساسی بر اساس اقدامات معلم بسازیم:
- قد هر دانش آموز را بخواهید و به مجموع دویدن اضافه کنید.
- کل را بر تعداد کل دانش آموزان تقسیم کنید.
مرحله اول برای هر دانش آموز یک بار اجرا می شود و نیازی به دانستن تعداد دانش آموزان کلاس ندارد. مرحله دوم صرف نظر از تعداد دانش آموزان کلاس فقط یک بار اجرا می شود. برای مرحله اول به یک حلقه نیاز داریم.
در اینجا کل الگوریتم در پایتون به نظر می رسد، از جمله یک حلقه for:
student_heights = [60, 65, 56, 71, 58, 63, 67]
height_sum = 0
for height in student_heights:
height_sum = height_sum + height
average_height = height_sum // len(student_heights)
print(average_height)
بنابراین، حلقه for Python بارها و بارها یک بلوک کد را اجرا می کند. به این “تکرار” نیز گفته می شود. حلقه ها تکرار یک فرآیند را برای چندین عنصر از یک دنباله امکان پذیر می کند. حلقههای For زمانی در پایتون استفاده میشوند که بتوان اندازه یک دنباله را در زمان اجرای برنامه تعیین کرد. در غیر این صورت معمولا از حلقه while استفاده می شود.
استفاده از حلقه در پایتون : تفاوت حلقه for در پایتون با زبان های دیگر چیست؟
بسیاری از زبان های برنامه نویسی دیگر حلقه ها را به نوعی پیاده سازی می کنند. آنها برای زبان هایی مانند C، جاوا، جاوا اسکریپت و PHP اساسی هستند. زبان های برنامه نویسی کاملا کاربردی مانند Haskell و Lisp معمولاً از حلقه های واضح استفاده نمی کنند. آنها به جای تکرار از توابع بازگشتی استفاده می کنند.
هر حلقه شامل اجرای مکرر یک بلوک کد است. با این حال، حلقه for در پایتون به طور اساسی متفاوت از حلقههای زبانهای دیگر عمل میکند. اکثر زبان های برنامه نویسی از یک متغیر حلقه استفاده می کنند که با هر بار تکرار موفق حلقه افزایش یا کاهش می یابد.
عمل | معنی | Typical syntax | Python syntax |
---|---|---|---|
افزایش | مقدار یک متغیر عدد صحیح را با مقدار مشخص و ثابتی افزایش دهید | i++ | index += 1 |
کاهش | مقدار یک متغیر عدد صحیح را با مقدار مشخص و ثابتی کاهش دهید | i– | index -= 1 |
برای اینکه ببینیم چگونه این تفاوت ایجاد می کند، بیایید نگاهی به مثالی از نحوه کار حلقه های for در زبان های دیگر بیندازیم. ما اعداد 0 تا 9 را در جاوا اسکریپت با یک حلقه for خروجی خواهیم داد. برای انجام این کار، یک متغیر عدد صحیح به نام “number” تعریف می کنیم و اگر مقدار آن کمتر از 10 باشد، آن را افزایش می دهیم. کد این مورد در جاوا اسکریپت احتمالا برای مبتدیان نامفهوم به نظر می رسد:
for ( let number = 0; number < 10; number++ ) {
console.log(number);
}
از سوی دیگر، دنبال کردن کد مربوط به حلقه for مشابه در پایتون به طور قابل توجهی ساده تر است:
for number in range(10):
print(number)
به جای خروجی مستقیم متغیر حلقه، معمولاً از یک عنصر از یک مجموعه برای نمایه سازی استفاده می شود. بیایید به مثال دیگری از جاوا اسکریپت نگاه کنیم، که در آن نامها را از لیست «افراد» خارج میکنیم. ما از متغیر حلقه “i” به عنوان شاخص در حال اجرا عناصر جداگانه استفاده خواهیم کرد:
people = ['Jack', 'Jim', 'John']
for (let i = 0; i < people.length; i++) {
console.log("Here comes " + people[i]);
}
مراقب ایندکس کردن مستقیم عناصر متوالی در یک لیست باشید. اگر حلقه یک بار بیش از حد اجرا شود، در نهایت با یک خطای زمان اجرا مواجه خواهید شد، که اغلب با خطای بدنام «خطای یک به یک» است. پایتون این مشکل را برطرف می کند. در زیر همان مورد پیاده سازی شده در پایتون را نشان می دهیم.
ما روی عناصر لیست بدون ایندکس کردن آنها با استفاده از یک متغیر حلقه تکرار می کنیم:
people = ['Jack', 'Jim', 'John']
for person in people:
print(f"Here comes {person}")
استفاده غیرمستقیم از متغیرهای حلقه منجر به سردرگمی زیادی برای یادگیری حلقههای for در زبانهایی غیر از پایتون میشود. متغیر حلقه در مرکز کد قرار دارد، حتی اگر معمولاً نقش مهمی ایفا نمی کند – تنها هدف آن ایندکس کردن عناصر منفرد است. هر کسی که امیدوار است از حلقه های معمولی استفاده کند، باید چندین موضوع پیچیده دیگر را درک کند. به عنوان مثال، در جاوا اسکریپت:
موضوع | در جاوا اسکریپت برای حلقه |
---|---|
تخصیص متغیر | let i = 0 |
عبارات بولی | i < limit |
عملگر افزایش/کاهش | i++ / i– |
تعیین اندازه لیست | i < list.length |
نمایه سازی بر اساس صفر عناصر | i < list.length is ok; i <= list.length results in off-by-one error |
حلقه for در پایتون به طور قابل توجهی کاربر پسندتر است. علیرغم استفاده از همان کلمه «برای»، رویکردی اساساً متفاوت دارد. به جای افزایش یک متغیر حلقه و نمایه سازی عناصر متوالی، مستقیماً روی عناصر در یک دنباله تکرار می شود. حلقه for در پایتون قابل مقایسه با ساختار forEach است که در زبان هایی مانند Ruby و JavaScript یافت می شود.
به عنوان مثال، فرض کنید می خواهیم حروف جداگانه یک کلمه را خروجی بگیریم. یک حرف از طریق متغیر “letter” برای هر تکرار حلقه در دسترس خواهد بود. بدون متغیر حلقه انجام می شود، به این معنی که خطر خطای off-by-one وجود ندارد. کد دقیق و به راحتی قابل خواندن است:
word = "Python"
for letter in word:
print(letter)
استفاده از حلقه در پایتون : حلقه for در پایتون چگونه کار می کند؟
همانطور که دیدیم، حلقه for Python به زیبایی مشکل تکرار عناصر در یک لیست را حل می کند. کلید کنار گذاشتن متغیر حلقه است. اما چگونه کار می کند؟ برای اینکه بفهمید Python for loop چگونه کار می کند، ابتدا باید کمی در مورد تکرار شونده ها و تکرار کننده ها بدانید.
تکرار شونده ها، تکرار کننده ها و مولدها چیست؟
در پایتون، حلقه for روی اشیایی که به عنوان “تکرار” شناخته می شوند، عمل می کند. این شامل رشته ها، لیست ها، تاپل ها و سایر مجموعه های داده است.
یک شیء تکرارپذیر دو ویژگی دارد:
- چندین عنصر را به عنوان یک مجموعه گرد هم می آورد.
- دسترسی به عناصر را از طریق یک تکرار کننده فراهم می کند.
با کنار هم قرار دادن این دو نکته، میتوان گفت که تکرارپذیرها مجموعههایی هستند که میتوان محتوای آنها را تکرار کرد. به طور خاص، تکرارشونده ها دارای یک روش “iter()” هستند که یک تکرار کننده تولید می کند. تکرار کننده شی ای است که می تواند عنصر بعدی یک تکرارپذیر را در دستور برگرداند. یک تکرار کننده همچنین موقعیت آخرین شیء برگشتی از مجموعه را به خاطر می آورد.
تابع | توضیح | مثال |
---|---|---|
iter(collection) | متد iter() مجموعه را فراخوانی می کند | it = iter(“Python”) |
next(iter) | متد next() تکرار کننده را فراخوانی می کند | next(it) |
collection[index] | متد getitem(index) مجموعه را فراخوانی می کند | ‘Python'[1] |
هنگامی که متد next() فراخوانی می شود، تکرار کننده عنصر بعدی را برمی گرداند.
زمانی که تمام عناصر مجموعه برگردانده شوند، تکرار کننده تمام می شود. با فراخوانی مجدد next() استثناء “StopIteration” ایجاد می شود.
بیایید با استفاده از یک مثال به نحوه عملکرد همه اینها در عمل نگاهی بیندازیم. ما یک شی range() ایجاد می کنیم که اعداد متوالی از 21 تا 23 را نشان می دهد. سپس یک تکرار کننده با تابع ()iter ایجاد می کنیم و عناصر متوالی را با تابع ()next برمی گردانیم. استثنا در آخرین تماس مطرح می شود، زیرا تکرار کننده تمام شده است:
numbers = range(21, 24)
number = iter(numbers)
next(number)
# returns `21`
next(number)
# returns `22`
next(number)
# returns `23`
next(number)
# raises `StopIteration` exception
تکرار کننده دسترسی به عناصر مجزا در یک مجموعه را فراهم می کند. علاوه بر این، مفهوم مرتبط با ژنراتور وجود دارد. برخلاف تکرارکننده، یک مولد عناصر فردی را در زمان دسترسی ایجاد میکند. این استفاده از “اجرای تنبل” باعث صرفه جویی در حافظه می شود.
ژنراتورها در پایتون توابعی هستند که حداقل یک عبارت بازدهی دارند. مشابه دستور return، عبارت yield یک شی را برمیگرداند و تماس را پایان میدهد. با این حال، بر خلاف دستور بازگشت، بیانیه بازدهی از جایی که در تماس های متوالی متوقف شد، ادامه می یابد.
بیایید به یک مثال نگاه کنیم. ما پیاده سازی خودمان از تابع range() را با استفاده از یک عبارت yield در حلقه while برای تولید اعداد پیوسته می نویسیم:
def my_range(start, stop):
if stop < start:
return None
current = start
while current < stop:
yield current
current += 1
# test
assert list(my_range(7, 9)) == list(range(7, 9))
پرش از تکرارها و خاتمه یک حلقه for در پایتون
گاهی اوقات لازم است از تکرارهای تکی یک حلقه صرفنظر کنید. مانند زبان های دیگر، پایتون یک عبارت ادامه برای پرش به تکرار بعدی دارد.
عبارت continue را می توان بسیار شبیه بازگشت زودهنگام استفاده کرد. به عنوان مثال، ممکن است بخواهیم پس از مشخص شدن اینکه مجموعه داده مشخصه مورد نظر ما را ندارد، از یک تکرار عبور کنیم:
def process_data(data):
for data_set in data:
data_set.validate()
# early continue after cheap check fails
if not data_set.quality_ok():
continue
# expensive operation guarded by early continue
data_set.process()
یا به عنوان مثالی دیگر، یک متن را خروجی می دهیم و از هر حرف دیگر می گذریم:
text = 'Skipping every second letter'
for index, letter in enumerate(text):
if index % 2 != 0 and letter != ' ':
continue
print(letter)
علاوه بر دستور continue، دستور break نیز وجود دارد که حلقه را خاتمه می دهد. نقش شکست در حلقه ها مشابه نقش بازگشت در توابع است.
دستور break اغلب در الگوریتم های جستجو استفاده می شود. اگر عنصر مورد جستجو پیدا شد، نیازی به اجرای تکرارهای بیشتر نیست. در مثال زیر، لیست را برای وجود یک مقدار واقعی بررسی می کنیم و زمانی که یک مقدار را پیدا کردیم، آن را خاتمه می دهیم:
bool_list = [False, False, True, False]
for index, boolean in enumerate(bool_list):
if boolean:
print(f"Value at position {index + 1} is True")
print(f"Aborting inspection of remaining {len(bool_list) - index - 1} item(s)")
break
حلقههای For در پایتون میتوانند حاوی بدنههای «دیگر» اختیاری باشند. وقتی حلقه خاتمه مییابد، بدون اینکه دستور break اجرا شده باشد، بدنه else اجرا میشود:
def find_element(target, collection):
for element in collection:
if element == target:
print("Found what you're looking for")
break
else:
print("Didn't find what you were looking for")
# test
find_element('a', 'Python')
find_element('o', 'Python')
حلقه های For در پایتون اغلب به عنوان بخشی از توابع ظاهر می شوند. در این مورد، به جای دستور break، از دستور return استفاده می کنید. به این نسخه جایگزین الگوریتم جستجوی ما بدون وقفه و موارد دیگر نگاهی بیندازید:
def find_element(target, collection):
for element in collection:
if element == target:
print("Found what you're looking for")
# returning breaks us out of the loop
return element
# we made it here without returning
print("Didn't find what you were looking for")
return None
# test
print(find_element('a', 'Python'))
print(find_element('o', 'Python'))
بهترین روش برای حلقه ها در پایتون چیست؟
حلقههای For در پایتون عمدتاً برای تکرار روی عناصر یک دنباله یا مجموعه استفاده میشوند. اما روش های مستقیم تری نیز برای بسیاری از موارد استفاده رایج وجود دارد. در زیر به برخی از بهترین شیوه ها و ضد الگوها نگاه خواهیم کرد. ابتدا باید این عبارات کلیدی را مرور کنید:
مدت، اصطلاح | توضیح | مثال |
---|---|---|
Collection | چندین عنصر که در کنار هم قرار گرفته اند. یک مجموعه تکرارپذیر است | (‘Walter’, ‘White’), [4, 2, 6, 9], ‘Python’ |
Iterator | رابط برای تکرار روی مجموعه ها | it = iter(‘Python’) |
Generator | تابعی که از بیانیه بازدهی به جای عبارت بازگشتی استفاده می کند. یک ژنراتور تکرارپذیر است | range(10) |
Comprehension | بیان تکراری؛ یک مجموعه جدید بر اساس تکرار شونده ایجاد می کند |
تکرار مستقیم روی عناصر یک مجموعه
یکی از اشتباهاتی که اغلب توسط مبتدیان مرتکب می شوند، استفاده از تابع len () به عنوان محدودیتی برای تابع range() است. این یک متغیر حلقه عددی ایجاد می کند که عناصر مجزای مجموعه را نمایه می کند.
word = 'Python'
for i in range(len(word)):
print(word[i])
این ضدالگو با دلیل موجهی نادیده گرفته شده است. خیلی بهتر است از حلقه Python for برای تکرار مستقیم روی عناصر یک مجموعه استفاده کنید:
word = 'Python'
for letter in word:
print(letter)
فهرست کردن عناصر در یک مجموعه با enumerate()، از جمله شاخص
گاهی اوقات شما به نمایه یک عنصر در یک مجموعه نیاز دارید. به جای ایجاد ایندکس به عنوان یک متغیر حلقه، از تابع ()enumerate استفاده کنید. تابع تاپل (شاخص، عنصر) را برمی گرداند. اطمینان حاصل کنید که شاخص شروع به شمارش از صفر می کند.
names = ["Jim", "Jack", "John"]
for index, name in enumerate(names):
print(f"{index + 1}. {name}")
تکرار بر روی تاپل ها با تابع zip().
وضعیت دیگری که اغلب ایجاد می شود، تکرار همزمان عناصر از دو مجموعه با طول مساوی است. رویکرد Python برای این وضعیت از تابع zip() استفاده می کند که دو مجموعه با اندازه یکسان را می گیرد و 2-tuples را برمی گرداند:
people = ('Jim', 'Jack', 'John')
ages = (42, 69, 13)
# ascertain both collections are same length
assert len(people) == len(ages)
# iterate over tuples of (person, age)
for person, age in zip(people, ages):
print(f"{person} is {age} years old")
ایجاد یک متغیر حلقه عددی با تابع range().
حلقههای For معمولاً در پایتون برای تکرار روی عناصر یک مجموعه استفاده میشوند. آنها معمولاً برای افزایش یک عدد صحیح استفاده نمی شوند. بهترین راه برای انجام این کار این است که یک شی range با استفاده از تابع range() ایجاد کنید و روی آن تکرار کنید:
for counter in range(10):
print(counter)
استفاده از عملگر in برای آزمایش اینکه آیا یک مجموعه حاوی عنصر است یا خیر
یافتن یک عنصر از درون یک مجموعه یک ابزار اساسی برای هر برنامه نویسی است. به طور معمول، شما از تابعی استفاده میکنید که روی عناصر تکرار میشود و هر عنصر را با عنصری که جستجو میشود بررسی میکند. وقتی عنصر پیدا شد، تکرار خاتمه می یابد.
در پایتون یک عملگر ویژه برای این منظور وجود دارد، عملگر in. بررسی می کند که آیا یک مجموعه حاوی عنصر مورد جستجو است یا خیر و مقدار بولی مربوطه را برمی گرداند:
'a' in 'Python'
'y' in 'Python'
ایجاد یک لیست از یک iterable با استفاده از تابع list().
برخلاف بسیاری از زبان های برنامه نویسی دیگر، برای آوردن حروف جداگانه از یک رشته به یک لیست، نیازی به استفاده از حلقه for در پایتون ندارید. در پایتون، میتوانید از تابع list() برای تبدیل یک تکرارپذیر به فهرستی از عناصر استفاده کنید. بیایید نگاهی به این دو رویکرد متفاوت بیندازیم. با استفاده از روش اول، حروف را در یک کلمه تکرار می کنیم و آنها را در یک لیست خالی قرار می دهیم:
word = 'Python'
letters = []
for letter in word:
letters.append(letter)
ما می توانیم خود را از تمام این مراحل اضافی نجات دهیم. با استفاده از روش دوم، می توانیم بلافاصله با تابع list() یک لیست ایجاد کنیم. در همان زمان، میتوانیم بررسی کنیم که این دو رویکرد نتیجه یکسانی دارند:
assert list(word) == letters
بیایید به مثال دیگری نگاه کنیم. ما لیستی از اعداد صفر تا نه را با استفاده از یک شی محدوده به عنوان تکرارپذیر ایجاد می کنیم:
list(range(10))
مانند لیست ها، مجموعه ها نیز می توانند با استفاده از تکرار شونده ایجاد شوند. در زیر مجموعه ای ایجاد می کنیم که شامل تمام حروف یک جمله خاص است. سپس از عملگر in استفاده می کنیم تا بررسی کنیم که مجموعه حاوی “a” نباشد:
alphabet = set('Python is not hyped')
assert 'a' not in alphabet
جایگزینی پایتون برای حلقه ها با درک
یکی از کاربردهای رایج برای حلقهها در پایتون، اصلاح عناصر یک مجموعه است. برای مثال، ممکن است بخواهید مقادیر جدیدی را بر اساس یک مجموعه محاسبه کنید یا عناصر خاصی را فیلتر کنید. مراحل انجام این کار با حلقه for به شرح زیر است:
- با استفاده از حلقه for روی مجموعه تکرار کنید.
- هر عنصر را پردازش کنید.
- در صورت لزوم، یک مجموعه جدید از زیر مجموعه عناصر ایجاد کنید.
این کار برای تغییرات ساده بسیار کار است. زبان های کاربردی به ما نشان می دهند که می تواند آسان تر باشد. خوشبختانه پایتون دارای درک است که می تواند در موارد ساده جایگزین حلقه ها شود و عملکرد بهتری داشته باشد.
درک ها مجموعه های اصلاح شده را بر اساس تکرارپذیرها با استفاده از نحو مختصر و مؤثر ایجاد می کنند. بیایید نگاهی به نحو کلی درک لیست بیندازیم. عبارت را در پرانتز می نویسیم. در این مثال، عملیاتی بر روی عناصر یک مجموعه انجام می شود و هر عنصر در یک لیست جدید کپی می شود:
[ operation(element) for element in collection ]
عناصر را می توان با استفاده از دستور if و شرط فیلتر کرد:
[ operation(element) for element in collection if condition(element) ]
حال بیایید نگاهی به مثالی از یک حلقه for در پایتون بیندازیم که می تواند با یک درک جایگزین شود. ما با لیستی از اعداد شروع می کنیم و می خواهیم لیستی از مربع های آنها را محاسبه کنیم:
numbers = [2, 3, 5, 9, 17]
اگر می خواستیم از یک حلقه for استفاده کنیم، یک لیست خالی ایجاد می کنیم و آن را با مربع ها به عنوان بخشی از حلقه پر می کنیم:
squares = []
for number in numbers:
squares.append(number ** 2)
با این حال، این را می توان با استفاده از یک درک بسیار آسان تر انجام داد:
squares_comp = [number ** 2 for number in numbers]
میتوانیم از عبارت assert برای بررسی اینکه آیا این دو رویکرد نتیجه یکسانی ارائه میدهند یا خیر استفاده کنیم:
assert squares == squares_comp
بیایید به مثال دیگری نگاهی بیندازیم. فرض کنید می خواهیم تمام حروف کوچک را از یک رشته استخراج کنیم. ابتدا لیستی متشکل از حروف کوچک و بزرگ ایجاد می کنیم:
word = list("PyThoN")
اگر بخواهیم از یک حلقه for استفاده کنیم، حروف را تکرار می کنیم و هر حرف را با استفاده از تابع islower() آزمایش می کنیم. کسانی که در آزمون موفق شوند به یک لیست خالی اضافه می شوند:
lowers = []
for letter in word:
if letter.islower():
lowers.append(letter)
با این حال، نیازی به این حلقه for در پایتون نیست. در عوض، از یک درک استفاده می کنیم، که فقط حروف کوچک را از لیست اصلی کپی می کند:
lowers_comp = [ letter for letter in word if letter.islower() ]
در نهایت، ما دوباره از عبارت assert استفاده می کنیم تا مطمئن شویم که این دو رویکرد نتیجه یکسانی را ارائه می دهند:
assert lowers == lowers_comp
استفاده از حلقه در پایتون
ترجمه شده توسط سایت دریای شرق از سایت
کپی بدون ذکر نام و لینک سایت دریای شرق ممنوع است !