В этой статье, моей последней статье об изучении Python, я расскажу о некоторых особенностях языка, о которых не упоминал в своих предыдущих статьях.

Условные выражения

Самый распространенный способ написать условное выражение — использовать оператор if-else, как в этом примере:

evenOdd = ""
if number % 2 == 0:
  evenOdd = "even"
else:
  evenOdd = "odd"

Это стандартная конструкция, но есть более краткий способ сделать это, используя так называемое условное выражение. Вот шаблон синтаксиса для условного выражения:

оператор0 if (условие) оператор1 else оператор2

Мы можем записать приведенный выше пример более кратко с условным выражением, как показано ниже:

number = int(input("Enter a number: "))
evenOdd = "even" if number % 2 == 0 else "odd"
print(number,"is",evenOdd)

Вот результат двух запусков этой программы:

C:\python>test.py
Enter a number: 23
23 is odd
C:\python>test.py
Enter a number: 22
22 is even

Вот еще один пример из замечательной книги о Python Think Python Аллена Дауни. Ниже приведено рекурсивное определение для вычисления факториала числа вместе с тестовой программой:

def factorial(n):
  if n == 0:
    return 1
  else:
    return n * factorial(n-1)
print(factorial(3))
print(factorial(5))

Вывод этой программы:

6
120

Функцию factorial можно записать более лаконично, используя условное выражение. Вот переопределение factorial вместе с той же тестовой программой:

def factorial(n):
  return 1 if n == 1 else n * factorial(n-1)
print(factorial(3))
print(factorial(5))

Результат:

6
120

Я оставлю вам решать, предпочитаете ли вы использовать условное выражение, а не традиционный оператор if-else, но имейте в виду, что краткость не всегда улучшает читабельность.

Список понятий

Понимание списка позволяет вам выполнять задачу для всех элементов в списке без использования цикла. Пример поможет объяснить, как работает понимание списка.

Следующая функция суммирует символы всех слов в списке, используя for loop:

def sumChars(lyst):
  total = 0
  for word in lyst:
    total += len(word)
  return total

Вот функция, используемая в программе:

words = ["hello","goodbye","walrus","blackbird"]
print(sumChars(words)) # outputs 27

Вот переписывание этой функции с использованием понимания списка:

def sum_chars(lyst):
  return sum([len(word) for word in lyst])

Эта функция перебирает список слов так же, как и первая функция, но в новом определении строится список длин слов, как указано в квадратных скобках. Затем для каждой длины слова вызывается функция суммы, чтобы получить общее количество символов в списке.

Генерация списков позволяет писать более краткий код Python, но их также может быть сложнее отлаживать, потому что вы не можете поместить какие-либо операторы отладки в интерпретацию списка, как вы можете сделать это в цикле for первого определения функции.

Понимание списка можно использовать для фильтрации набора элементов. Например, если у меня есть набор результатов тестов, и я хочу отфильтровать все оценки, отличные от A (менее 90), я могу написать следующую функцию, используя понимание списка:

def onlyA(grades):
  return [grade for grade in grades if grade >= 90]

Вот тестовая программа:

grades = [81, 92, 77, 94, 68, 100, 79, 90]
print(onlyA(grades))

Вывод этой программы:

[92, 94, 100, 90]

Выражения генератора

Выражение генератора вычисляет значение, которое может быть частью последовательности. Например, вы можете использовать генераторное выражение для вычисления ряда чисел, возведенных в степень.

Когда вы создаете выражение генератора, вы не создаете полный набор значений, как вы делаете с генератором списка. Вместо этого вы создаете выражение, которое будет генерировать следующее значение на основе указанного вычисления, которое вы используете в выражении.

Вот простое генераторное выражение, которое вычисляет квадрат следующего числа в последовательности, а также программа для его проверки:

gen = (num * num for num in range(1,11))
for i in range(1,6):
  print(i,next(gen))

Вывод этой программы:

1 1
2 4
3 9
4 16
5 25

Мой следующий пример вычисляет заданное количество элементов в ряду Фибоначчи. Это вычисление требует использования оператора yield в функции, вычисляющей числа Фибоначчи, вместо оператора return. Здесь — это объяснение того, что делает инструкция yield.

Теперь, когда вы понимаете, как работает yield, я могу представить свой код генератора рядов Фибоначчи вместе с тестовой программой:

def fibo():
  a,b = 0,1
  while True:
    yield a
    a,b = b, a + b
fib = fibo() # generator
count = 0
for f in fib:
  print(f, end=" ")
  count += 1
  if (count > 10):
    break

Вот вывод этой программы:

0 1 1 2 3 5 8 13 21 34 55

Правда, эта программа вычисляет определенное количество чисел Фибоначчи. Я оставлю читателю в качестве упражнения изменить программу так, чтобы пользователь сам определял, сколько чисел Фибоначчи печатает программа.

Любая функция

Функция any — это встроенная логическая функция, которая проверяет заданное условие в контейнере значений и возвращает значение True, если какой-либо из элементов контейнера соответствует условию. Вот шаблон синтаксиса для any:

Boolean-return-value any(условие, набор элементов)

Вот первый пример:

grades = [81, 92, 78, 91, 100, 65, 88]
flag = any(grade >= 90 for grade in grades)
if flag:
  print("There are A grades in set of grades.")
else:
  print("There are no A grades in set of grades.")

Функция any проверяет, есть ли в списке оценок оценка выше или равная 90, и возвращает True, если да, и False в противном случае.

Вот еще один пример использования строки вместо списка:

def isVowel(letter):
  return letter == 'a' or \
         letter == 'e' or \
         letter == 'i' or \
         letter == 'o' or \
         letter == 'u'
word = "hello"
flag = any(isVowel(letter) for letter in word)
if flag:
  print("There is at least one vowel in",word)
else:
  print("There are no vowels in",word)
word = "crwth"
flag = any(isVowel(letter) for letter in word)
if flag:
  print("There is at least one vowel in",word)
else:
  print("There are no vowels in",word)

Вывод этой программы:

There is at least one vowel in hello
There are no vowels in crwth

Все функции

Функция all противоположна функции any. Она возвращает True, если каждый элемент контейнера соответствует указанному условию, и функция возвращает False в противном случае. Вот пример использования функции all (код и результат двух прогонов):

def isVowel(letter):
  return letter == 'a' or \
         letter == 'e' or \
         letter == 'i' or \
         letter == 'o' or \
         letter == 'u'
# Eunoia
word = input("Enter a word: ")
flag = all(isVowel(letter) for letter in word)
if (flag):
  print(word,"is all vowels.")
else:
  print(word,"is not all vowels.")
C:\python>test.py
Enter a word: euoia
euoia is all vowels.
C:\python>test.py
Enter a word: hello
hello is not all vowels.

Еще две структуры данных

В Python есть пара структур данных, о которых я не рассказывал в своих предыдущих статьях. Первым из них является набор.

Набор — это неупорядоченный, нетипизированный набор значений, в котором не может быть дубликатов. Наборы создаются с помощью фигурных скобок, например:

fruit = {"apple", "banana", "melon"}

После того, как набор создан, вы не можете удалять или изменять элементы набора, но вы можете добавлять новые элементы в набор, используя метод add. Вот пример:

fruit = {"apple", "banana", "melon"}
print(fruit)
fruit.add("kiwi")
print(fruit)
fruit.add("apple")
print(fruit)

Вывод этой программы:

{'apple', 'banana', 'melon'}
{'apple', 'banana', 'melon', 'kiwi'}
{'apple', 'banana', 'melon', 'kiwi'}

Функция len работает и с множествами:

fruit = {"apple", "banana", "melon"}
print(fruit)
fruit.add("kiwi")
print(fruit)
fruit.add("apple")
print(fruit)
print("Number of items in set:",len(fruit))
# displays Number of items in set: 4

В качестве последнего примера вы можете объединить два набора, используя метод update:

myFruit = {"apple", "banana"}
yourFruit = {"banana", "kiwi", "melon"}
myFruit.update(yourFruit)
print(myFruit)

Вывод этой программы:

{'banana', 'apple', 'kiwi', 'melon'}

Вторая структура данных, о которой я хочу рассказать, это счетчик. Счетчик хранит элементы как набор, но если к счетчику добавляется неуникальный элемент, счетчик отслеживает, сколько раз этот элемент появляется. Во многих отношениях счетчик похож на словарь, где ключ — это элемент, а значение — количество вхождений ключа.

Счетчик не является встроенной структурой данных, поэтому его необходимо импортировать, как вы увидите в программе ниже.

Вот программа, которая демонстрирует силу Counter в работе в качестве согласования слов:

from collections import Counter
letter_count = Counter("supercalifragiliciousexpealidocious")
print(letter_count)

Вывод этой программы:

Counter({'i': 6, 's': 3, 'u': 3, 'e': 3, 'c': 3, 'a': 3, 'l': 3, 'o': 3, 'p': 2, 'r': 2, 'f': 1, 'g': 1, 'x': 1, 'd': 1})

На этом мы завершаем эту статью и мою серию статей об изучении Python. Спасибо за прочтение этой серии и, пожалуйста, напишите мне по адресу [email protected] с вашими комментариями и предложениями.