17.流式编程

予早 2024-10-05 10:54:57
Categories: Tags:

在链式编程的基础上实现流式编程

https://pypi.org/project/more-itertools/

标准库工具

map

返回一个map对象

r = map(lambda x: x + 1, [1, 2, 3])
print(type(r), r)

print(list(r))
# [2, 3, 4]

sorted

非原地排序,排序并返回一个新的列表

r = sorted((2, 1, 3))

print(type(r), r)  # <class 'list'> [1, 2, 3]

filter

过滤,返回一个filter对象

r = filter(lambda x: x > 2, [1, 2, 3])
print(type(r), r)
print(list(r))

# <class 'filter'> <filter object at 0x000001F87FC39FA0>
# [3]

reversed

r = reversed([1, 2, 3])

print(type(r), r)
print(list(r))

# <class 'list_reverseiterator'> <list_reverseiterator object at 0x0000019F3262CEE0>
# [3, 2, 1]

groupby

from itertools import groupby

for key, group in groupby("AAABBBCCAAA"):
    print(key, list(group))
# A["A", "A", "A"]
# B ['B', 'B', 'B']
# C ['C', 'C']
# A ['A', 'A', 'A']

先排序再分组

https://docs.python.org/zh-cn/3/library/operator.html

import operator
from itertools import groupby
from operator import itemgetter
from typing import Iterable


def items2str(d: dict, keys: Iterable, sep: str = ""):
    return sep.join([str(d.get(key)) for key in keys])


data = [
    {"name": "Alice", "age": 25},
    {"name": "Bob", "age": 30},
    {"name": "Charlie", "age": 25},
    {"name": "David", "age": 30},
]

grouped_data = groupby(data, key=itemgetter("age"))

for key, group in grouped_data:
    print(f"Key: {key}")
    for item in group:
        print(f"  {item}")

# 先按 'age' 键排序
data.sort(key=itemgetter("age"))

# 根据 'age' 键进行分组
grouped_data = groupby(data, key=itemgetter("age"))

for key, group in grouped_data:
    print(f"Key: {key}")
    for item in group:
        print(f"  {item}")

data = [
    {"name": "Alice", "age": 25},
    {"name": "Bob", "age": 30},
    {"name": "Charlie", "age": 25},
    {"name": "David", "age": None},
]

data.sort(key=lambda x: items2str(x, ("age",)))
grouped_data = groupby(data, key=itemgetter("age"))


for key, group in grouped_data:
    print(f"Key: {key}")
    for item in group:
        print(f"  {item}")

repeat

import itertools


r = itertools.repeat(1, 6)
print(type(r), r)
print(list(r))
# <class 'itertools.repeat'> repeat(1, 6)
# [1, 1, 1, 1, 1, 1]

# repeat 的复制
l = list(itertools.repeat([6, [8]], 5))
print(l)
l[0] = 1
l[1][1] = 1
print(l)
# [[6, [8]], [6, [8]], [6, [8]], [6, [8]], [6, [8]]]
# [1, [6, 1], [6, 1], [6, 1], [6, 1]]

toolz

Stream

from toolz import groupby


class Stream:
    def __init__(self, o):
        self.o = o

    def map(self, func):
        self.o = map(func, self.o)
        return self

    def filter(self, func):
        self.o = filter(func, self.o)
        return self

    def sorted(self, key=None, reverse=False):
        self.o = sorted(self.o, key=key, reverse=reverse)
        return self

    def reversed(self):
        self.o = reversed(self.o)
        return self

    def groupby(self, key):
        self.o = groupby(key, self.o)
        return self

    def to_list(self):
        return list(self.o)


print(Stream([1, 2, 3]).map(lambda x: x * 2).sorted().reversed().to_list())
# [6, 4, 2]