Коли в програміста виникає необхідність повторити якусь дію кілька разів, він пише цикл. У python є оператори циклу 'while' та 'for'. У більшості випадків оператори циклу взаємозамінні, але кожен з них має деякі нюанси.
Найпростіший оператор циклу while виглядає так:
while умова: дія
або
while умова: блок дій в декілька рядків
Логічно і синтаксично оператор циклу while дуже схожий з оператором розгалуження if.
У обох випадках відбувається перевірка умови, і у разі її істинності (тобто умова=True) виконуються команди, які у такому випадку називаються "тілом циклу". І, так само як і у випадку з if, у циклів у Пайтоні може бути повне розгалуження із застосуванням гілки 'else', яке буде виконуватись у разі хибності умови (тобто умова=False).
Головна відмінність між if та while полягає у тому, що при розгалуженні команди виконуються одноразово, а у циклі інтерпретатор повертається до початкової перевірки умови після кожного повтору циклу.
i = res = 0
while i < 11:
res += i
i += 1
print(res)while i > 0:
i -= 1
print(i)
else:
print("end")У програмуванні часто використовуються вічні цикли. Просто є ситуації, коли немає явного обмеження і умову важко перевірити заздалегідь. Для того, щоб вийти з вічного циклу і взагалі з циклу, використовується оператор break. Він працює всередині циклу та припиняє його виконання. Далі проілюстровано роботу оператора break та оператора continue, який припиняє поточну ітерацію та починає наступну:
i = 10
while True:
i -= 1
if not i: continue
if i%2:
print(i)
if i < -10: breakУ цій можливості оператору while криється його небезпека: якщо неграмотно скласти обробку умови та її зміну всередині тіла циклу, то він легко увійде у режим вічного повтору і програма може просто підвиснути. Також у циклу while, завдяки факту перевірки умови ПЕРЕД здійсненням дій з інформацією є можливість, при неграмотному складанні алгоритму вчинити одну лишню ітерацію (повтор тіла циклу) і видати результат відмінний від очікуваного. Цих недоліків позбавлений наступний оператор циклу, який деякі ортодоксальні програмісти також прирівнюють до "синтаксичного цукру".
На відміну від while оператор циклу for має явно вказану кінцевість, оскільки здійснює повтори виключно згідно з кількістю елементів ітерованого об'єкта, який йому передається.
Те саме підсумовування перших 10 елементів, що й за допомогою циклу while, але за допомогою for:
sum = 0
for i in range(1, 11):
sum += i
print(sum)У цьому випадку використано генераторний вираз range(a,b,c), який створює послідовність цілих чисел починаючи з a до, але не включаючи b, з кроком c. Слід зазначити, що для даного генератора параметри a та c не є обов'язковими.
Оскільки цикл for виконується в рамках ітерованого об'єкта, то він чуже часто використовується для перебору значень цього самого ітерованого об'єкта (рядка, генератора, списку, кортежу тощо):
sum = []
for i in 'word':
sum += i
print(sum)Бувають ситуації, коли виникає необхідність не просто поелементного перебору ітерованого об'єкта, але й встановлення індексу кожного його елемента. У цьому випадку використовується метод enumerate(), котрий додає до ітерованого об'єкта лічильник і повертає його у вигляді нумерованого об'єкта. Цей нумерований об'єкт надалі може бути використаний напряму у циклах for або конвертований у список, кожен елемент якого є кортежем, за допомогою функції list().
Синтаксис функції:
enumerate(iterable, start=0)
де: iterable - ітерований об'єкт; start - початкове значення індексу (0 за замовчуванням)
a = [10, 20, 30, 40]
for id, item in enumerate(a):
a[id] = item + 5
print(a)
[15, 25, 35, 45]Слід зазначити, що внутрішня реалізація у Пайтоні циклу for є швидшою за код циклу while. І при одних і тих самих умовах цикл for виконається приблизно на 20-50% швидше.
В роботі з файлом є наступні можливості: файл треба відкривати, писати туди, читати з файлу та закривати його.
Функція open відкриває файл з прешого параметру у режимі (методі), вказаному в другому параметрі.
filename = 'test.txt'
# далі відкриваємо файл для читання (опція 'r')
f = open(filename, 'r') # в файлі тепер file descriptor
for line in f: # для кожного рядка у файлі
print(line)
f.close() # закриття файлуМетоди відкриття файлів:
rвідкриває файл для читання, і це є параметр за замовченнямr+відкриває на читання та записwвідкриває файл для запису, створює новий файл у разі його відсутності, видаляє зміст файлу, якщо той вже існуєw+відкриває файл для читання та запису, так само створює новий файл у разі його відсутності, видаляє зміст файлу, якщо той вже існуєaвідкриває файл для доповнення, пише в кфнець файлуa+відкриває файл для читання та запису, пише в кінець файлу
Для читання інформації з файлу треба виклакати метод в дескріптора файлу. Для цього є наступні стандартні методи:
readдозволяє прочитати весь зміст файлу в один рядок;readlinesдозволяє прочитати весь зміст файлу в один список;readlineдозволяє читає по черзі кожний рядок файлу до ентеру в рядок. Може замінюватись на звичайний проход по цикл.
Також дуже зручним є підхід для читання файла порядково через цикл for, як в прикладі на open.
Приклади:
# Маємо 3 файли
filename1 = 'test1.txt'
filename2 = 'test2.txt'
filename3 = 'test3.txt'#1. Method READ, reads whole file as a string
#-----
f1 = open(filename1)
content1 = f1.read() # as a string
f1.close()#2. Method READLINES, reads whole file as a list
#-----
f2 = open(filename2)
content2 = f2.readlines() # as a list
f2.close()#3. Method READLINE, reads file by line
#-----
f3 = open('filename3')
count = 0
while True:
count += 1
line = f3.readline()
if not line:
break
print(f"{count}. : {line.strip()}")
f3.close()Метод write пише до файлу переданий йому рядок.
Метод writelines пише до файлу переданий йому список рядків.
#1. Method WRITE, wrtes a string
#-----
f=open('file.txt','w')
f.write('hello')
f.close()
#2. Method WRITELINES, writes list of strings
#-----
f1 = open("file1.txt", "w")
lst = 'Welcome to the club'.split()
f1.writelines(lst)
f1.close() У багатьох підручниках записано такий приклад для запису і закриття файлу:
f=open('file.txt','w')
f.write('hello')
f.close()Це вірно, але призводить до багатьох помилок. При виникненні будь якої повʼязаної із файлом чи ні помилки в той промідок часу, коли айл було відкрито, але ще не закрито, він ніколи не буде закритий. Тому варто використовувати контекстний менеджер with.
Оператор контекстного менеджера автоматично закриває файл, коли виконання блоку with закінчується. Це означає, що ви більше не маєте проблеми з закриттям файлу вручну, що допомагає уникнути помилок, пов'язаних з відкриттям та закриттям файлів, які можуть виникнути, якщо ви відкриєте файл вручну, і забудете закрити його пізніше. Також його використання робить код більш читабельним.
with open('f1.txt', 'r') as f:
for line in f:
print(line)У python між одинарними й подвійними лапками практично немає різниці, а ще є два види потрійних. Всі типи лапок можуть бути вставлені одні в одні. Потрійні так же дозволяють перехід на новий рядок всередині рядка:
S1 = 'Welcome to strings'
S2 = "Another string"
S3 = """And '''another'''
long
string"""
S4 = 'This "string" is a bit """crazy"""'Прості арифметичні операції складання і множення доступні і з рядками. У прикладі нижче - складання двох рядків (конкатенація), множення рядка на число та взяття конкретного елемента рядка за його індексом. Індекси у всіх послідовностях у програмуванні вважаються від нуля. По негативному індексу - відраховуємо від кінця рядка назад.
S = 'abc'
print (len(S)) # 3
S = S + '12' # В S = 'abc12'
print (S[2]) # 'c'
print ('ab'*2) # 'abab'>>> S
'Welcome to California!'
>>> len(S) # get length of the string
22
>>> S.find('C') # get index of the first substring found
11
>>> S.replace('C', '7') # Replaces all the substrings to the new one mentioned
'Welcome to 7alifornia!'
>>> S.split() # Cuts the string using the separator provided, creates a list. By default space is used as a separator
['Welcome', 'to', 'California!']
>>> S.upper()
'WELCOME TO CALIFORNIA!'
>>> S += '\n\n'
>>> S
'Welcome to California!\n\n'
>>> S.rstrip() # removes space-like symbols at the end of string
'Welcome to California!'Додаткову інформацію про рядки та функції роботи з ними можна знайти за посиланням: Детальніше про рядки
Python дозволяє взяти частину рядка або навіть скласти з елементів рядка будь-який новий рядок, використовуючи фрагменти (зрізи). Приклади:
>>> S = "Welcome to California!"
>>> S
'Welcome to California!'
>>> S[:5]
'Welco'
>>> S[5:]
'me to California!'
>>> S[:]
'Welcome to California!'
>>> S[:-3]
'Welcome to Californ'
>>> S[::-1]
'!ainrofilaC ot emocleW'
>>> S[:5:2]
'Wlo'З прикладу видно, що зрізи створюються шляхом вказівки у квадратних дужках обов'язкової двокрапки. Число до двокрапки - від якого елемента показувати, після - до якого, не включаючи його. Якщо не вказано перше число - показати від початку, якщо не вказано друге - до кінця. Друга двокрапка дозволяє вказати третє число - крок, з яким потрібно йти по послідовності.
Списки задаються багатьма способами:
# empty list
>>>empty_list = []
# Simple listing
>>> a = [2, 2.25, "Python"]
>>> a
[2, 2.25, 'Python']
# Transforming the string to a list
>>> b = list("help")
>>> b
['h', 'e', 'l', 'p']
>>> b = 'welcome to the hell'.split()
>>> b
['welcome', 'to', 'the', 'hell']До списків застосовні всі зрізи, що застосовуються до рядків. На додаток, до списків таким чином можна ще й додавати нові елементи.
L = [1, 2, 's']
>>> L
[1, 2, 's']
>>> L[1:3]
[2, 's']
>>> L[2] = '17'
>>> L
[1, 2, '17']
>>> L[1:2]
[2]
>>> L[1:2] = ['new', 'list']
>>> L
[1, 'new', 'list', '17']>>> L = list(range(1, 11))
>>> L
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> L.append(12) # Adds element at the end of the list
>>> L
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12]
>>> L.extend([13, 14]) # Adds second's list elements to the end of the first list
>>> L
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14]
>>> L.insert(2, 5) # Insert 5 to the second place (index)
>>> L
[1, 2, 5, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14]
>>> L.remove(5) # Removes the first 5 appeared
>>> L
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14]>>> L
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# map function applies the method given to the iterable proposed
>>> L = list(map(str, range(1, 11)))
>>> L # Here we have casted all integers to strings
['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
>>> S = ': '.join(L) # concats small strings into one big, using "glue". Starts as a method of "glue"
>>> S
'1: 2: 3: 4: 5: 6: 7: 8: 9: 10'Цикл for спеціально створений для того, щоб виконувати повторювані дії з ітерованими об'єктами, утому числі зі списками. Пара прикладів:
>>> S = 'This is Sparta!!'
>>> L = S.split()
>>> L
['This', 'is', 'Sparta!!']
>>> for elem in L:
... print('say ' + elem)
...
say This
say is
say Sparta!!
>>> for num, elem in enumerate(L):
... print (str(num) + '. say ' + elem)
...
0. say This
1. say is
2. say Sparta!!Зверніть увагу на функцію enumerate, яка видає не лише вміст списку, а і його порядковий номер.
У мовах програмування є таке поняття, як синтаксичний цукор. Це можливості мови за деяким спрощенням мовних конструкцій, які не впливають на виконання конструкцій, але спрощують життя програміста. Найпопулярніший і найпоширеніший приклад - спискові включення, list comprehensions.
Нижче наведено приклади приведення звичайного циклу до спискового включення:
>>> l = []
>>> for x in range(1, 11):
... l.append(x*x)
...
>>> l
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
# now with the list comprehension
>>> l2 = [x*x for x in range(1, 11)]
>>> l2
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]Синтаксис у list comprehensions приблизно такий:
result_list = [actions_with_var for var in list if condition]
Як видно з синтаксису, можна навіть додати перевірку певної умови, по виконанні якої ми додаватимемо або не додаватимемо елемент до результівного списку:
e = 's o m e t e x t'
a = [x*2 for x in e if x!=' ']
print(a)
# ['ss', 'oo', 'mm', 'ee', 'tt', 'ee', 'xx', 'tt']Насправді ця конструкція є прикладом генераторного виразу, що перевіряється обрамленням її не квардатними, а круглими дужками і перевіркою типу даних на виході:
>>> a=(x for x in range(10))
>>> type(a)
<class 'generator'>А у прикладах наведених вище відбувалося перетворення згенерованих даних на льоту у елементи списку, завдяки ініціалізації змінної, як списку.
List comprehensions за 5 хвилин
- Кожен пише суму списку за допомогою
forтаwhile - Написати програму, яка виводить сама себе
- Написати програму, яка виводить саму себе задом наперед
- Банкомат видає суму максимально можливими купюрами
- Банкомат видає суму дрібними, але не більше 10 штук кожної дрібної купюри
- Продовжуємо писати практики з заняття.
- Написати fizzbuzz для 20 комплектів по три числа, які записані в файл. Читайте із файлу перший рядок з трьома числами, беріть із нього числа, рахуйте для них fizzbuzz, виводите, продовжуйте з наступним рядком і так до кінця файла.
- Переробити другу задачу так, щоб результат писався в інший файл. Додаємо list comprehension, map та інші свіжеотримані знання до виконання завдання.
