Функции в Python. Часть II

Содержание

Вторая часть функций в Python (совсем базу вряд-ли буду выкладывать). Типы аргументов, некоторые встроенные и lambda функции

Необязательные и именованные аргументы

Позиционные аргументы

Когда мы вызываем функции c позиционными аргументами, значения в них подставляются согласно позиции их имен в определении функции. Например код ниже выведет число 7. При вызове функции diff() первому параметру x будет соответствовать первый переданный аргумент – 10, а второму параметру y – второй аргумент – 3.

1
2
3
4
5
6
def diff(x, y):
    return x - y


res = diff(10, 3)  # используем позиционные аргументы
print(res)

Именованные аргументы

Аргументы, передаваемые с именами, называются именованными. Чтобы передать именованные аргументы в функцию, нужно указать их имена, которые были заданы при объявлении функции:

1
2
3
4
5
6
7
8
9
def bar(length, char1, char2):
    return (char1 + char2) * length + char1

print(bar(length=3, char1='-', char2='*'))
# => -*-*-*-
print(bar(char1='-', char2='*', length=3))
# => -*-*-*-
print(bar(char2='*', length=3, char1='-'))
# => -*-*-*-

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

Совет
Рекомендация по тому, когда стоит использовать именованные аргументы: если функция принимает больше трёх аргументов, нужно хотя бы часть из них указать по имени.
1
2
3
4
def make_circle(x, y, radius, line_width, fill):
    # тело функции

make_circle(x=200, y=300, radius=17, line_width=2.5, fill=True)
Предупреждение
Мы можем вызывать функции, используя именованные и позиционные аргументы одновременно. Но позиционные значения должны быть указаны до любых именованных!

Необязательные аргументы

Бывает, что какой-то параметр функции часто принимает одно и то же значение. Например, для функции print() установили значения параметров sep и end равными символу пробела и символу перевода строки, поскольку эти значения используют наиболее часто.
Другим примером служит функция int(), преобразующая строку в число. Она принимает два аргумента: первый аргумент – строка, которую нужно преобразовать в число, второй аргумент – основание системы счисления, значение по умолчанию которого равно 10.

Чтобы задать значение параметра по умолчанию, в списке параметров функции достаточно после имени переменной написать знак равенства и нужное значение.
Параметры со значением по умолчанию идут последними.

Изменяемые типы данных в качестве значений по умолчанию

Рассмотрим определение функции append(), где в качестве значения по умолчанию используется изменяемый тип данных:

1
2
3
def append(element, seq=[]):
    seq.append(element)
    return seq

Если вызвать функцию так, то мы получим неожиданный результат:

1
2
3
print(append(10))
print(append(5))
print(append(1))
1
2
3
4
# Вывод:
[10]
[10, 5]
[10, 5, 1]

Значение по умолчанию для параметра создается единожды при определении функции (обычно при загрузке модуля) и становится её атрибутом (свойством). Поэтому, если значение по умолчанию изменяемый объект, то его изменение повлияет на каждый следующий вызов функции.
Для решения проблемы можно использовать константу None в качестве значения параметра по умолчанию, а в теле функции устанавливать нужное значение:

1
2
3
4
5
6
7
8
9
def append(element, seq=None):
    if seq is None:
        seq = []
    seq.append(element)
    return seq

print(append(10))
print(append(5))
print(append(1))
1
2
3
4
# Вывод:
[10]
[5]
[1]

Функции с переменным количеством аргументов

Позиционные аргументы – *args

Рассмотрим определение функции my_func():

1
2
3
4
5
6
7
8
def my_func(*args):
    print(type(args))
    print(args)


my_func()
my_func(1, 2, 3)
my_func('a', 'b')
1
2
3
4
5
6
7
# Вывод:
<class 'tuple'>
()
<class 'tuple'>
(1, 2, 3)
<class 'tuple'>
('a', 'b')
  • В заголовке функции my_func() указан всего один параметр args, но со звездочкой перед ним. Звездочка в определении функции означает, что переменная (параметр) args получит в виде кортежа все аргументы, переданные в функцию при ее вызове от текущей позиции и до конца.
  • При описании функции можно использовать только один параметр помеченный звездочкой, причем располагаться он должен в конце списка параметров, иначе последующим параметрам не достанется значений.
  • Параметр со звёздочкой работает, даже если не передать аргументов.

Если мы хотим просуммировать несколько разных значений, не упаковывая их в список, можем написать следующую функцию (списки и кортежи при вызове нужно распаковывать):

1
2
3
4
5
6
def my_sum(*args):
    return sum(args)

print(my_sum(1, 2, *[3, 4, 5], *(7, 8, 9), 10))

# Вывод: 49

Именованные аргументы – **kwargs

1
2
3
4
5
6
7
def my_func(**kwargs):
    print(type(kwargs))
    print(kwargs)

my_func()
my_func(a=1, b=2)
my_func(name='Timur', job='Teacher')
1
2
3
4
5
6
7
# Вывод:
<class 'dict'>
{}
<class 'dict'>
{'a': 1, 'b': 2}
<class 'dict'>
{'name': 'Timur', 'job': 'Teacher'}
  • Именованные аргументы получаются в виде словаря, что позволяет сохранить имена аргументов в ключах.
  • Именованные аргументы можно передавать в функцию “пачкой” в виде словаря. Для этого нужно перед словарём поставить две звёздочки.
  • Параметр **kwargs пишется в самом конце, после последнего аргумента со значением по умолчанию. При этом функция может содержать и *args и **kwargs параметры:
1
2
3
4
5
6
7
8
9
def my_func(a, b, *args, name='Gvido', age=17, **kwargs):
    print(a, b)
    print(args)
    print(name, age)
    print(kwargs)

my_func(1, 2, 3, 4, name='Timur', age=28, job='Teacher', language='Python')
my_func(1, 2, name='Timur', age=28, job='Teacher', language='Python')
my_func(1, 2, 3, 4, job='Teacher', language='Python')
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# Вывод:
1 2
(3, 4)
Timur 28
{'job': 'Teacher', 'language': 'Python'}

1 2
()
Timur 28
{'job': 'Teacher', 'language': 'Python'}

1 2
(3, 4)
Gvido 17
{'job': 'Teacher', 'language': 'Python'}

Keyword-only аргументы

В Python 3 добавили возможность пометить именованные аргументы функции так, чтобы вызвать функцию можно было, только передав эти аргументы по именам. Такие аргументы называются keyword-only и их нельзя передать в функцию в виде позиционных:

1
2
3
4
5
6
7
def make_circle(x, y, radius, *, line_width=1, fill=True):
    #код

make_circle(10, 20, 5)                                    # x=10, y=20, radius=5,  line_width=1, fill=True
make_circle(x=10, y=20, radius=7)                         # x=10, y=20, radius=7,  line_width=1, fill=True
make_circle(10, 20, radius=10, line_width=2, fill=False)  # x=10, y=20, radius=10, line_width=2, fill=False
make_circle(x=10, y=20, radius=17, line_width=3)          # x=10, y=20, radius=17, line_width=3, fill=True

Здесь * выступает разделителем: отделяет обычные аргументы (их можно указывать по имени и позиционно) от строго именованных.
То есть аргументы x, y и radius могут быть переданы в качестве как позиционных, так и именованных аргументов. При этом аргументы line_width и fill могут быть переданы только как именованные аргументы.
Такой разделитель можно использовать только один раз в определении функции. Его нельзя применять в функциях с неограниченным количеством позиционных аргументов *args.


Функции как объекты

Встроенные функции имеют следующий тип объекта:

1
2
3
print(type(print))

# <class 'builtin_function_or_method'>

Тогда как функции, объявленные программистом, имеют тип <class 'function'>.

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

1
2
3
4
5
6
7
8
def hello():
    print('Hello from function')


func = hello  #  присваиваем переменной func функцию hello
func()        #  вызываем функцию

# Вывод: Hello from function
1
2
3
4
writeln = print

writeln('Hello world!')
writeln('Python')
1
2
3
# Вывод:
Hello world!
Python

Присваивание переменной списка функций:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
def f(x):
    return x**2


def g(x):
    return x**3


funcs = [f, g]
print(funcs[0](5), funcs[1](5))

# Вывод: 25 125
Инфо
Функции, способные в качестве аргумента принимать или/и возвращать другие функции, называются функциями высшего порядка.
Функция, определяющая условия сравнения элементов, называется компаратор.

Такие встроенные функции, как min(), max(), sorted() могут принимать необязательный аргумент key – функцию, определяющую, по какому правилу будут сравниваться элементы (значение key должно быть функцией, принимающей один аргумент и возвращающей на его основе ключ для сравнения).

1
2
3
4
5
numbers = [10, -7, 8, -100, -50, 32, 87, 117, -210]

print(max(numbers, key=abs))
print(min(numbers, key=abs))
print(sorted(numbers, key=abs))
1
2
3
4
# Вывод:
-210  # максимальный по модулю элемент
-7    # минимальный по модулю элемент
[-7, 8, 10, 32, -50, 87, -100, 117, -210] 
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
def compare_by_second(point):
    return point[1]


def compare_by_sum(point):
    return point[0] + point[1]


points = [(1, -1), (2, 3), (-10, 15), (10, 9), (7, 18), (1, 5), (2, -4)]

print(sorted(points, key=compare_by_second))  # сортируем по второму значению кортежа
print(sorted(points, key=compare_by_sum))     # сортируем по сумме кортежа

Функции в качестве возвращаемых значений других функций

В Python можно определять функцию внутри функции, ведь функция это объект:

1
2
3
4
5
6
7
8
9
def generator():
    def hello():
        print('Hello from function!')
    return hello

func = generator()
func()

# Вывод: Hello from function!

Мы можем написать генератор функций, который по параметрам a,b,c, построит и вернет нам конкретный квадратный трехчлен:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
def generator_square_polynom(a, b, c):
    def square_polynom(x):
        return a * x**2 + b * x + c

    return square_polynom

f = generator_square_polynom(a=1, b=2, c=1)
g = generator_square_polynom(a=2, b=0, c=-3)
h = generator_square_polynom(a=-3, b=-10, c=50)

print(f(1))
print(g(2))
print(h(-1))
1
2
3
4
# Вывод:
4
5
57

Вложенную функцию (square_polynom()), которая использует параметры внешней функции (generator_square_polynom()), называют замыканием.


Пользовательские атрибуты функций

У объектов функций есть дополнительный атрибут __dict__, являющийся словарем и использующийся для динамического наделения функций дополнительным функционалом. Устанавливать и получать значения из данного атрибута можно, используя два синтаксиса:

  • в стиле словаря: func.__dict__['attr'] = value
  • через точечную нотацию: func.attr = value
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
def greet():
    greet.age = 17

print(greet.__dict__)

greet.value = 777
greet.numbers = [1, 2, 3]
greet.name = 'Timur'

print(greet.__dict__)

greet()

print(greet.__dict__)
1
2
3
4
# Вывод:
{}
{'value': 777, 'numbers': [1, 2, 3], 'name': 'Timur'}
{'value': 777, 'numbers': [1, 2, 3], 'name': 'Timur', 'age': 17}

Словарь атрибутов может быть использован для кэширования уже вычисленных значений функции:

1
2
3
4
5
6
def fib(num):
    if num < 2:
        return num
    if num not in fib.__dict__:
        fib.__dict__[num] = fib(num - 1) + fib(num - 2)
    return fib.__dict__[num]

Функции высшего порядка

Функции, которые принимают и/или возвращают другие функции, называются функциями высшего порядка.

Функция map()

Функция, преобразующая каждый элемент переданного итерируемого объекта (можно воспринимать как классическое представление функции в математике – отображение множества в другое множество).
Возможная реализация:

1
2
3
4
5
6
7
def map(function, items):
    result = []
    for item in items:
        new_item = function(item)
        result.append(new_item)

    return result

Мы можем совершать преобразования, используя функцию высшего порядка map():

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
def square(x):
    return x**2


def cube(x):
    return x**3


numbers = [1, 2, -3, 4, -5, 6, -9, 0]

strings = map(str, numbers)      # используем в качестве преобразователя функцию str
abs_numbers = map(abs, numbers)  # используем в качестве преобразователя функцию abs

squares = map(square, numbers)   # используем в качестве преобразователя функцию square
cubes = map(cube, numbers)       # используем в качестве преобразователя функцию cube

print(strings)
print(abs_numbers)
print(squares)
print(cubes)
1
2
3
4
5
# Вывод:
['1', '2', '-3', '4', '-5', '6', '-9', '0']
[1, 2, 3, 4, 5, 6, 9, 0]
[1, 4, 9, 16, 25, 36, 81, 0]
[1, 8, -27, 64, -125, 216, -729, 0]

Мы также можем строить цепочки преобразований, несколько раз вызывая функцию map() (сначала мы преобразуем список строк в список чисел, затем находим их модуль внешней функцией map()):

1
2
3
4
5
numbers = ['-1', '20', '3', '-94', '65', '6', '-970', '8']
new_numbers = map(abs, map(int, numbers))
print(new_numbers)

# Вывод: [1, 20, 3, 94, 65, 6, 970, 8]

Функция filter()

Эта функция отображает часть элементов итерируемого объекта по определённому критерию.
Возможная реализация:

1
2
3
4
5
6
7
def filter(function, items):
    result = []
    for item in items:
        if function(item):        
            result.append(item)  # добавляем элемент item если функция function вернула значение True

    return result

Функция filter() применяет предикат function к каждому элементу и добавляет в итоговый список только те элементы, для которых предикат вернул True.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
def is_odd(num):
    return num % 2


def is_word_long(word):
    return len(word) > 6


numbers = list(range(15))
words = ['В', 'новом', 'списке', 'останутся', 'только', 'длинные', 'слова']

odd_numbers = filter(is_odd, numbers)
large_words = filter(is_word_long, words)

print(odd_numbers)
print(large_words)
1
2
3
# Вывод:
[1, 3, 5, 7, 9, 11, 13]
['останутся', 'длинные']

Функция reduce()

Функция, применяющая указанную функцию к элементам последовательности, сводя её к единственному значению.
Возможная реализация:

1
2
3
4
5
6
def reduce(operation, items, initial_value):
    acc = initial_value
    for item in items:
        acc = operation(acc, item)

    return acc
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
def add(x, y):
    return x+y


def mult(x, y):
    return x*y


numbers = [1, 2, 3, 4, 5]

total = reduce(add, numbers, 0)
product = reduce(mult, numbers, 1)

print(total)
print(product)
1
2
3
# Вывод:
15
120

Встроенные функции map(), filter(), reduce()

Встроенная функция map()

Функция, применяющая другую функцию к итерируемому объекту. Имеет сигнатуру map(func, *iterables). В отличии от нашей реализации она может принимать сразу несколько последовательностей, переменное количество аргументов. Под подпоследовательностями имеются ввиду списки, строки, кортежи, множества, словари.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
def increase(num):
    return num + 7


numbers = [1, 2, 3, 4, 5, 6]
new_numbers = map(increase, numbers)  # используем встроенную функцию map()

print(new_numbers)

# Вывод: <map object at 0x...>

Вернулся итерируемый объект <map object at 0x...>. Подобные ему объекты называются итераторами. Если мы хотим получить список/кортеж из итератора, нужно воспользоваться функцией list()/tuple(), а если распаковать, то * (при этом сделать эти действия возможно только единожды, т.к. итератор “исчерпывает” себя).

Функции map() можно передать несколько последовательностей. В этом случае в функцию обратного вызова func будут передаваться сразу несколько элементов, расположенных в последовательностях на одинаковых позициях. При этом, если в последовательностях разное количество элементов, то последовательность с минимальным количеством элементов становится ограничителем.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
def func(elem1, elem2, elem3):
    return elem1 + elem2 + elem3


numbers1 = [1, 2, 3, 4, 5]
numbers2 = [10, 20, 30, 40, 50]
numbers3 = [100, 200, 300, 400, 500]

new_numbers = list(map(func, numbers1, numbers2, numbers3))  # преобразуем итератор в список

print(new_numbers)

# Вывод: [111, 222, 333, 444, 555]

Пример удобного использования функции map(), которой передано две последовательности:

1
2
3
4
5
6
7
8
circle_areas = [3.56773, 5.57668, 4.31914, 6.20241, 91.01344, 32.01213]

result1 = list(map(round, circle_areas, [1]*6))        # округляем числа до 1 знака после запятой
result2 = list(map(round, circle_areas, range(1, 7)))  # округляем числа до 1,2,...,6 знаков после запятой

print(circle_areas)
print(result1)
print(result2)
1
2
3
4
# Вывод:
[3.56773, 5.57668, 4.31914, 6.20241, 91.01344, 32.01213]
[3.6, 5.6, 4.3, 6.2, 91.0, 32.0]
[3.6, 5.58, 4.319, 6.2024, 91.01344, 32.01213]

Встроенная функция filter()

Функция отображает часть элементов итерируемого объекта по определённому критерию. Имеет сигнатуру filter(func, iterable). В отличии от нашей реализации она может принимать любой итерируемый объект (список, строку, кортеж, и т.д.).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
def func(elem):
    return elem >= 0


numbers = [-1, 2, -3, 4, 0, -20, 10]
positive_numbers = list(filter(func, numbers))  # преобразуем итератор в список

print(positive_numbers)

# Вывод: [2, 4, 0, 10]

Функция filter() также возвращает итератор.

Встроенной функции filter() можно в качестве первого параметра func передать значение None. В таком случае каждый элемент последовательности будет проверен на соответствие значению True. Если элемент в логическом контексте возвращает значение False, то он не будет добавлен в возвращаемый результат. В следующем коде значения списка [0, '', None, [], ()] позиционируется как False:

1
2
3
4
true_values = filter(None, [1, 0, 10, '', None, [], [1, 2, 3], ()])

for value in true_values:
    print(value)
1
2
3
4
# Вывод:
1
10
[1, 2, 3]

Функция reduce()

Для использования: from functools import reduce.

Функция, применяющая указанную функцию к элементам последовательности, сводя её к единственному значению. Имеет сигнатуру reduce(func, iterable, initializer=None). Если начальное значение не установлено, то в его качестве используется первое значение из последовательности iterable.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from functools import reduce


def func(a, b):
    return a + b


numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
total = reduce(func, numbers, 0)  # в качестве начального значения 0
print(total)

# Вывод: 55

Анонимные функции

lambda – безымянные однострочные функции (называются анонимными или лямбда-функциями). По сути эти функции являются выражениями, при этом они имеют такой же тип данных, как обычные функции – <class 'function'>. После определения их можно сразу вызвать: print((lambda х, у: х + у)(5, 10)) # 5 + 10. Общий формат определения: lambda список_параметров: выражение. В теле лямбда-функции нельзя использовать несколько действий и циклы, но можно использовать тернарный условный оператор. Применение таких функций оправдано в следующих случаях:

  • однократное использование функции;
  • передача функций в качестве аргумента другим функциям;
  • возвращение функции в качестве результата другой функции.
1
2
3
4
5
6
7
def standard_function(x):        #  стандартное объявление функции
    return x*2

lambda_function = lambda x: x*2  #  объявление анонимной функции

print(standard_function(7))
print(lambda_function(7))
1
2
3
# Вывод:
14
14
1
2
3
4
5
6
7
f1 = lambda: 10 + 20            # функция без параметров
f2 = lambda х, у: х + у         # функция с двумя параметрами
f3 = lambda х, у, z: х + у + z  # функция с тремя параметрами

print(f1())
print(f2(5, 10))
print(f3(5, 10, 30))

Лямбда-функции для нетипичной сортировки кортежей:

1
2
3
4
points = [(1, -1), (2, 3), (-10, 15), (10, 9), (7, 18), (1, 5), (2, -4)]

print(sorted(points, key=lambda point: point[1]))             # сортируем по второму значению кортежа
print(sorted(points, key=lambda point: point[0] + point[1]))  # сортируем по сумме элементов кортежа

Передача лямбда-функций в качестве аргументов

  • Функция map():
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
numbers = [1, 2, 3, 4, 5, 6]

new_numbers1 = list(map(lambda x: x+1, numbers))   # увеличиваем на 1
new_numbers2 = list(map(lambda x: x*2, numbers))   # удваиваем
new_numbers3 = list(map(lambda x: x**2, numbers))  # возводим в квадрат


strings = ['a', 'b', 'c', 'd', 'e']
numbers = [3, 2, 1, 4, 5]

new_strings = list(map(lambda x, y: x*y, strings, numbers))
  • Функция filter():
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
numbers = [-1, 2, -3, 4, 0, -20, 10, 30, -40, 50, 100, 90]

positive_numbers = list(filter(lambda x: x > 0, numbers))   # положительные числа
large_numbers = list(filter(lambda x: x > 50, numbers))     # числа, большие 50
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))  # четные числа


words = ['python', 'stepik', 'beegeek', 'iq-option']

new_words1 = list(filter(lambda w: len(w) > 6, words))  # слова длиною больше 6 символов
new_words2 = list(filter(lambda w: 'e' in w, words))    # слова содержащие букву e
  • Функция reduce():
1
2
3
4
5
6
7
8
from functools import reduce

words = ['python', 'stepik', 'beegeek', 'iq-option']
numbers = [1, 2, 3, 4, 5, 6]

summa = reduce(lambda x, y: x + y, numbers, 0)
product = reduce(lambda x, y: x * y, numbers, 1)
sentence = reduce(lambda x, y: x + ' loves ' + y, words, 'Everyone')
1
2
3
4
# Вывод:
21
720
Everyone loves python loves stepik loves beegeek loves iq-option

Возвращение лямбда-функции в качестве результата другой функции

Следующий пример показывает, что анонимные функции являются замыканиями, т.е. возвращаемая функция запоминает значения переменных a, b, c из внешнего окружения:

1
2
def generator_square_polynom(a, b, c):
    return lambda x: a*x**2 + b*x + c

Условный оператор в теле лямбда-функции

Общий вид: значение1 if условие else значение2.

1
2
3
4
5
6
7
numbers = [-2, 0, 1, 2, 17, 4, 5, 6]

result = list(map(lambda x: 'even' if x % 2 == 0 else 'odd', numbers))

print(result)

# Вывод: ['even', 'even', 'odd', 'even', 'odd', 'even', 'odd', 'even']

Передача аргументов в анонимную функцию

Анонимные функции поддерживают все способы передачи аргументов:

  • позиционные;
  • именованные;
  • *args – переменный список позиционных аргументов;
  • **kwargs – переменный список именованных аргументов;
  • * – обязательные аргументы.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
f1 = lambda x, y, z: x + y + z
f2 = lambda x, y, z=3: x + y + z
f3 = lambda *args: sum(args)
f4 = lambda **kwargs: sum(kwargs.values())
f5 = lambda x, *, y=0, z=0: x + y + z


print(f1(1, 2, 3))
print(f2(1, 2))
print(f2(1, y=2))
print(f3(1, 2, 3, 4, 5))
print(f4(one=1, two=2, three=3))
print(f5(1))
print(f5(1, y=2, z=3))
1
2
3
4
5
6
7
8
# Вывод:
6
6
6
15
6
1
6

Функции any(), all(), zip(), enumerate()

Функция all()

Встроенная функция all() возвращает значение True, если все элементы переданной ей коллекции истинны, и False в противном случае. При работе со словарями функция all() проверяет на соответствие параметрам True ключи словаря.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
print(all([1, 2, 3]))   
print(all([1, 2, 3, 0, 5]))
print(all([True, 0, 1]))
print(all(('', 'red', 'green')))
print(all({0j, 3+4j}))

print()

dict1 = {0: 'Zero', 1: 'One', 2: 'Two'}
dict2 = {'Zero': 0, 'One': 1, 'Two': 2}
print(all(dict1))
print(all(dict2))
1
2
3
4
5
6
7
8
9
# Вывод:
True
False
False
False
False

False
True

Если переданный итерируемый объект пуст, то функция all() возвращает значение True.

1
2
3
4
print(all([]))        # передаем пустой список
print(all(()))        # передаем пустой кортеж
print(all(''))        # передаем пустую строку
print(all([[], []]))  # передаем список, содержащий пустые списки
1
2
3
4
5
# Вывод:
True
True
True
False

Функция any()

Встроенная функция any() возвращает значение True, если хотя бы один элемент переданной ей коллекции является истинным, и False в противном случае. При работе со словарями функция any() проверяет на соответствие True ключи словаря.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
print(any([0, 0, 0]))
print(any([0, 1, 0]))
print(any([False, 0, 1]))
print(any(['', [], 'green']))
print(any({0j, 3+4j, 0.0}))

print()

dict1 = {0: 'Zero'}
dict2 = {'Zero': 0, 'One': 1}
print(any(dict1))
print(any(dict2))
1
2
3
4
5
6
7
8
9
# Вывод:
False
True
True
True
True

False
True

Если переданный итерируемый объект пуст, то функция any() возвращает значение False.

1
2
3
4
print(any([]))        # передаем пустой список
print(any(()))        # передаем пустой кортеж
print(any(''))        # передаем пустую строку
print(any([[], []]))  # передаем список, содержащий пустые списки
1
2
3
4
5
# Вывод:
False
False
False
False

Функции all(), any() в связке с map()

Следующий код проверяет, все ли элементы списка больше 10:

1
2
3
4
5
6
7
8
numbers = [17, 90, 78, 56, 231, 45, 5, 89, 91, 11, 19]

result = all(map(lambda x: True if x > 10 else False, numbers))  # анонимную функцию можно упростить до lambda x: x > 10

if result:
    print('Все числа больше 10')
else:
    print('Хотя бы одно число меньше или равно 10')

Следующий код проверяет, чётен ли хотя бы один элемент коллекции:

1
2
3
4
5
6
7
8
numbers = [17, 91, 78, 55, 231, 45, 5, 89, 99, 11, 19]

result = any(map(lambda x: x % 2 == 0, numbers))

if result:
    print('Хотя бы одно число четное')
else:
    print('Все числа нечетные')

Функция enumerate()

Встроенная функция enumerate() возвращает кортеж из индекса элемента и самого элемента переданной ей коллекции: enumerate(iterable, start), где iterable – итерируемый объект (коллекция), а start – необязательный параметр, задающий начальное значение индекса (по умолчанию start = 0). Эта функция возвращает объект-итератор, который можно перебрать, преобразовать в список функцией list() или распаковать *.

1
2
3
4
colors = ['red', 'green', 'blue']
print(list(enumerate(colors, start=1)))

# Вывод: [(1, 'red'), (2, 'green'), (3, 'blue')]

Функция zip()

Встроенная функция zip() объединяет отдельные элементы из каждой переданной ей коллекции в кортежи. Также возвращает итератор, который можно перебрать, преобразовать или распаковать. Если функции zip() передать итерируемые объекты, имеющие разную длину, то объект с наименьшим количеством элементов определяет итоговую длину.

1
2
3
4
5
6
7
8
numbers = [1, 2, 3, 4]
words = ['one', 'two']
romans = ['I', 'II', 'III']

result = zip(numbers, words, romans)
print(list(result))

# Вывод: [(1, 'one', 'I'), (2, 'two', 'II')]
1
2
3
4
5
6
7
8
numbers = [1, 2, 3]
words = ['one', 'two', 'three']
romans = ['I', 'II', 'III']

result = zip(numbers, words, romans)
print(list(result))

# Вывод: [(1, 'one', 'I'), (2, 'two', 'II'), (3, 'three', 'III')]

Частые случаи использования zip():

  • Для создания словарей, если ключи и значения находятся в разных списках:
1
2
3
4
5
6
7
keys = ['name', 'age', 'gender']
values = ['Timur', 28, 'male']

info = dict(zip(keys, values))
print(info)

# Вывод: {'name': 'Timur', 'age': 28, 'gender': 'male'}
  • Для параллельного итерирования по разным коллекциям:
1
2
3
4
5
name = ['Timur', 'Ruslan', 'Rustam']
age = [28, 21, 19]

for x, y in zip(name, age):
    print(x, y)
1
2
3
4
# Вывод:
Timur 28
Ruslan 21
Rustam 19
Поддержать автора
NoisyCake cloudtipscloudtips
0%