Встроенные функции Python для работы с коллекциями (sorted, filter, zip, reversed, len) | Way23

Встроенные функции Python для работы с коллекциями (sorted, filter, zip, reversed, len)

sorted()

Возвращает новый сортированный список (list) из элементов iterable.

print(sorted([5, 6, 2, 0])) # [0, 2, 5, 6]
1

Порядок элементов изменяется аргументом key. Переданная в key функция применяется к каждому элементу. Результат функции используется для определения порядка элементов:

def neg(n):
    return -n

print(sorted([5, 6, 2, 0], key = neg)) # [6, 5, 2, 0]
1
2
3
4

Логический аргумент reverse задаёт обратную сортировку:

print(sorted([5, 6, 2, 0], reverse = True)) # [6, 5, 2, 0]
1

Описание других способов сортировкиopen in new window.

zip(*iterables)

Одновременно перебирает элементы из нескольких итерируемых объектов. Возвращает итератор кортежей, в котором каждый i-тый кортеж содержит i-тый элемент из каждого аргумента.

a = [1, 2, 3]
b = [4, 5, 6]
c = [7, 8, 9]

print(*zip(a, b, c), sep='\n')

# (1, 4, 7)
# (2, 5, 8)
# (3, 6, 9)
1
2
3
4
5
6
7
8
9

Перебор заканчивается при завершении самого короткого аргумента:

a = [1, 2, 3]
b = [4, 5, 6]
c = [7, 8]

print(*zip(a, b, c), sep='\n')

# (1, 4, 7)
# (2, 5, 8)
1
2
3
4
5
6
7
8

При одном аргументе zip() возвращает кортежи из одного элемента:

a = [1, 2, 3]

print(*zip(a), sep='\n')

# (1,)
# (2,)
# (3,)
1
2
3
4
5
6
7

При пустом списке аргументов zip() возвращает пустой итератор:

print(*zip(), sep='\n')
1

Эквивалентный код на Python:

def zip(*iterables):
    # zip('ABCD', 'xy') --> Ax By
    sentinel = object()
    iterators = [iter(it) for it in iterables]
    while iterators:
        result = []
        for it in iterators:
            elem = next(it, sentinel)
            if elem is sentinel:
                return
            result.append(elem)
        yield tuple(result)
1
2
3
4
5
6
7
8
9
10
11
12

zip() используется со списками разных размеров только когда не имеют значения последние элементы самых больших списков. Если эти элементы имеют значение используйте itertools.zip_longest().

zip() вместе с оператором * может использоваться чтобы распаковать (unzip) список:

>>>
>>> x = [1, 2, 3]
>>> y = [4, 5, 6]
>>> zipped = zip(x, y)
>>> list(zipped)
[(1, 4), (2, 5), (3, 6)]
>>> x2, y2 = zip(*zip(x, y))
>>> x == list(x2) and y == list(y2)
True
1
2
3
4
5
6
7
8
9

Одновременный перебор двух коллекций:

a = 'hello'
b = 'hel1o'

for i, j in zip(a, b):
    if i != j:
        print(i, j)

# l 1
1
2
3
4
5
6
7
8

filter(function, iterable)

Фильтрует элементы, возвращает только те элементы для которых function возвращает True.

def is_even(x):
    return x % 2 == 0

a = [0, 1, 2, 3, 4, 5, 6]

print(*filter(is_even, a))
# 0 2 4 6

# эквивалентно генератору
print(*(item for item in a if is_even(item)))
# 0 2 4 6
1
2
3
4
5
6
7
8
9
10
11

Если function равен None то удаляются все элементы равные False:

print(*filter(None, a))
# 1 2 3 4 5 6

# эквивалентно генератору
print(*(item for item in a if item))
# 1 2 3 4 5 6
1
2
3
4
5
6

reversed(seq)

Переворачивает последовательность задом наперёд.

print(*reversed([1, 2, 3])) # 3 2 1
1

seq должен быть объектом с методом __reversed__():

class MyNumber():
    def __init__(self, num):
        self.num = num

    def __reversed__(self):
        return int(''.join(reversed(str(self.num))))

x = MyNumber(123)
print(reversed(x)) # 321
1
2
3
4
5
6
7
8
9

или поддерживать протокол последовательностей: методы __len__() и __getitem__() с целочисленными аргументами начиная с 0.


class MyNumber():
    def __init__(self, num):
        self.num = num

    def __len__(self):
        return len(str(self.num))

    def __getitem__(self, item):
        return str(self.num)[item]

x = MyNumber(123)
print(*reversed(x)) # 3 2 1
1
2
3
4
5
6
7
8
9
10
11
12
13

len(s)

Возвращает длину (количество элементов) объекта. Аргумент может быть последовательностью (string, bytes, tuple, list, range) или коллекцией (dictionary, set, frozen set).

print(len([1, 2, 5])) # 3
print(len({2, 3}))    # 2
print(len('hello'))   # 5

print(len([])) # 0
1
2
3
4
5

Ссылки

Последниее изменение: 31.08.2021, 15:52:51