# ===== CodeLab: Python 迭代器与生成器 =====
# 来源: https://aoerliang.dpdns.org/articles/python-iterators
# 以下代码片段按文章出现顺序拼接, 共 6 段

# ----- 片段 1 (python) -----
nums = [1, 2, 3]
it = iter(nums)          # 拿到迭代器
print(next(it))          # 1
print(next(it))          # 2
print(next(it))          # 3
# 再调用 next(it) 会抛 StopIteration

# ----- 片段 2 (python) -----
it = iter("abc")
while True:
    try:
        ch = next(it)
        print(ch)
    except StopIteration:
        break

# ----- 片段 3 (python) -----
def countdown(n):
    while n > 0:
        yield n
        n -= 1

for x in countdown(3):
    print(x)   # 3 2 1

# ----- 片段 4 (python) -----
squares = (x * x for x in range(10))
print(sum(squares))     # 285,边算边求和

# 对比:列表推导式会先建出整个列表
big = [x for x in range(1_000_000)]        # 占内存
big_gen = (x for x in range(1_000_000))    # 几乎不占

# ----- 片段 5 (python) -----
def errors_in_log(path):
    with open(path, encoding="utf-8") as f:
        for line in f:            # 惰性逐行,内存恒定
            if "ERROR" in line:
                yield line.strip()

for err in errors_in_log("app.log"):
    print(err)

# ----- 片段 6 (python) -----
from itertools import islice, chain, groupby

# 只取前 3 个
first3 = list(islice(range(100), 3))      # [0, 1, 2]

# 拼接多个迭代器
merged = list(chain("ab", "cd"))          # ['a', 'b', 'c', 'd']

# 按 key 分组(数据需先排序)
data = sorted(["a1", "a2", "b1"], key=lambda s: s[0])
for key, group in groupby(data, key=lambda s: s[0]):
    print(key, list(group))
