Python 技巧 - Iterable - 第一部分

发布日期:2026-07-19 09:11:05  来源 : 杭州电子商务研究院    浏览量 :0
杭州电子商务研究院 发布日期:2026-07-19 09:11:05  
0

介绍

编者注:本指南是实用 Python 技巧系列的一部分。阅读有关本系列的更多信息并在此处找到其他指南的链接。

在本指南中,我们将开始学习 Python 中的可迭代技巧,包括与可迭代相关的高级技能。每个 Python 技巧都分两个步骤进行解释:

  1. 概念的简要描述和交互式代码示例
  2. 一些鼓舞人心的例子来启发你

构造迭代器

以下是从Hackaday中摘取的迭代器的一些精细定义

迭代是一个表示数据流的对象。从技术上讲,它是一个具有__iter____next__方法的对象。

可迭代对象能够迭代的对象实际上,可迭代对象是具有__iter__方法的对象,该方法返回一个迭代器。字符串、列表、文件和字典都是可迭代对象的示例。

鼓舞人心的例子

这个例子对于迭代器来说是一个非常有创意的用法。in函数循环遍历同一个迭代器,以确保每个字符只按顺序检查一次。

      """construct iterator to make sure check every char only once by 'in' """
# L392: check if s is subsequence of t. s = "abc", t = "ahbgdc", return true.
def is_subsequence(s: str, t: str) -> bool:
    t = iter(t)
    return all(c in t for c in s)
    

构造生成器

生成器提供了一种简单的内置方法来创建迭代器实例。我们可以通过调用具有一个或多个yield表达式的函数来构建生成器。我们还可以用生成器表达式以理解的方式构造生成器,我们将在下面讨论。

生成器不会将所有值存储在内存中;它们会动态生成值。这是我们在Python 技巧 - 基础指南中讨论的惰性求值技术。

鼓舞人心的例子

为了简化逻辑,我们可以将结果构建为生成器样式。

      """generate all combinations of coins which sum to target amount"""
def get_coin_changes(coins: List[int], amount[int]) -> List[List[int]]:
    for i, coin in enumerate(coins):
        if coin == amount:
            yield (coin,)
        elif coin < amount:
            yield from ((coin,) + x for x in change(coins[i:], amount - coin))

"""generate all combinations of well-formed n pairs of parentheses"""
# L22: generate all combinations of well-formed n pairs of parentheses.
def generate_parenthesis(n: int) -> List[str]:
    def generate(p, left, right):
        if 0 <= left <= right:
            if not right:
                yield p
            for q in generate(p + '(', left-1, right): yield q
            for q in generate(p + ')', left, right-1): yield q
    return list(generate('', n, n))
    

理解

理解技术提供了一种基于现有序列构建新序列(如列表、集合、字典等)的简短而简洁的方法。

Python 提供以下四种类型的理解:

      """list comprehension"""
odds_list = [x for x in range(20) if x % 2]

"""generator_expression"""
odds_generator = (x for x in range(20) if x % 2)

"""set comprehension"""
odds_set = {x for x in range(20) if x % 2}

"""dict comprehension"""
square_dict = {x: x**2 for x in range(10)}
    

鼓舞人心的例子

以下示例演示了构建列表推导的高级技巧。它们还展示了各种应用场景。

      """bfs in list comprehension way"""
# L515: find the largest value in each row of a binary tree
def find_largest_in_binary_tree_rows(root: TreeNode) -> List[int]:
    maxes, row = [], [root]
    while any(row):
        maxes.append(max(node.val for node in row))
        row = [kid for node in row for kid in (node.left, node.right) if kid]
    return maxes

"""rotate image by list comprehension"""
# L48: rotate the image by 90 degrees (clockwise)
def rotate_image_90_degrees(matrix: List[List[int]]) -> None:
    matrix[:] = [[row[i] for row in matrix[::-1]] for i in range(len(A))]

"""generate combinations by list comprehension recursively"""
# L77: Given two integers n and k, return all possible combinations of k numbers out of 1 ... n.
def combine(n: int, k: int) -> List[List[int]]:
    if k == 0:
        return [[]]
    # add last element
    return [pre + [i] for i in range(k, n + 1) for pre in combine(i - 1, k - 1)]

"""generate binary trees by list comprehension recursively"""
# given an integer n, generate all structurally unique BST's (binary search trees) that store values 1 ... n.
def generate_binary_search_trees(last: int, first: int=1) -> List[TreeNode]:
    def node(val, left, right):
        node = TreeNode(val)
        node.left = left
        node.right = right
        return node
    return [node(root, left, right) 
            for root in range(first, last+1)
            for left in generate_binary_search_trees(root-1, first)
            for right in generate_binary_search_trees(last, root+1)] or [None]
    

拉姆达

lambda函数,也称为匿名函数,是具有隐式返回的单一表达式。lambda函数可以有任意数量的参数,但只能有一个表达式。

      lambda arguments : expression
    

鼓舞人心的例子

下面的示例展示了lambda的各种应用场景。

      """lambda used in lexical closure"""
def make_adder(n):
    return lambda x: x + n

plus_3 = make_adder(3)
plus_3(4)
# output: 7

"""lambda used in key"""
# sort dict by value
d = {'apple': 18, 'orange': 20, 'banana': 5, 'rotten tomato': 1}
sorted(d.items(), key=lambda x: x[1])
# alternative
from operator import itemgetter
sorted(d.items(), key=itemgetter(1))
# output: [('rotten tomato', 1), ('banana', 5), ('apple', 18), ('orange', 20)]

for pos in range(len(S)):
    """lambda used in filter"""
    matched_words = list(filter(lambda x: S[pos:].startswith(x), words))
    if matched_words:
        """lambda used in max"""
        add_interval([pos, pos + len(max(matched_words, key=lambda x: len(x)))])

"""call lambda in nested"""
# L422: given a sequence of words, check whether it forms a valid word square.
def valid_word_square(words: List[str]) -> bool:
    f = lambda x: map(None, *x)  # python 2
    return f(f(words)) == f(words)

"""use lambda to wrap parameter as callable"""
def wrapped_callable(f):
    if callable(f): return f
    else: return lambda: f
    

结论

在本指南中,我们学习了许多可迭代的 Python 技巧,例如迭代器、生成器、理解和 lambda。我希望其中一些对你有用。

第 2 部分中,我们将继续学习其他可迭代的 Python 技巧。

您还可以从 Github下载示例笔记本iterables.ipynb 。

本指南是 Python 技巧指南系列之一:

希望你喜欢。如果您有任何问题,欢迎通过 recnac@foxmail.com 与我联系。

以上内容来自杭州电子商务研究院推送
分享到:

长按或扫码识别 分享给好友

长按或扫码识别 分享给好友
关于我们
热门推荐
合作伙伴
免责声明:本站部分资讯来源于网络,如有侵权请及时联系客服,我们将尽快处理
Copyright © 2025-2027 ToB产业网址导航 公安备案 浙公网安备33010602013138号 浙ICP备16025413号-9
支持 反馈 关注 数据