zoukankan      html  css  js  c++  java
  • Python专题之详解enumerate和zip

    enumerate

    第一个是枚举函数。

    在我们的日常编程过程中,我们经常遇到一个问题。

    在C语言和一些古老的语言中没有迭代器的概念,所以当我们想要遍历数组或容器时,我们只能使用下标。使用迭代器,我们的遍历过程更加方便。我们可以直接使用变量来迭代容器中的值。最简单的例子是数组遍历。例如,我们需要遍历items数组。我们可以直接:

    for item in items:
    

    通过迭代器的方法,可以方便地遍历数组而不需要下标和计算数组的长度。但是如果我们需要知道循环体中元素的下标呢?

    我们真的需要在下标和迭代器之间进行选择吗,比如在循环体之外添加一个变量来记录下标?

    idx = 0
    
    for item in items:    
         operation()    
         idx += 1
    

    这可以解决问题,但很麻烦,一点也不简洁,专业术语也不是pythonic(Python标准代码)。为了追求pythonic,我们使用了枚举函数来解决直接迭代需要知道元素下标的情况。

    它的用法也很简单。我们将需要迭代的对象或迭代器传递到枚举函数中。它将为我们创建一个新的迭代器,并返回下标和迭代的内容。举个例子:

    for i, item in enumerate(items):
    

    此外,枚举还支持传入参数。例如,在某些情况下,我们希望下标从1开始,而不是从0开始。我们可以传递一个附加参数来实现这一点:

    for i, item in enumerate(items, 1):
    

    循环是我们编程中的一个基本操作。因此,枚举函数得到了广泛的应用。但是,应该注意的是,如果我们在一个多组数组上迭代,我们需要区分索引和值。例如:

    data = [(1, 3), (2, 1), (3, 3)]
    

    在不用enumerate的时候,我们有两种迭代方式,这两种都可以运行。

    for x, y in data:
    
    for (x, y) in data:
    

    但是,如果我们使用枚举,因为引入了索引,我们必须进行区分,否则会报告错误,因此我们只有一种迭代方法:

    for i, (x, y) in enumerate(data):
    

    zip

    接下来要介绍的另一个函数同样是方便我们迭代的,不过它针对的是另一个场景——多对象迭代。

    它的应用场景非常简单,就是我们想要同时迭代多份数据,比如用户的名字和用户的职业数据是分开的,我们希望同时遍历一个用户的职业和名字。如果不使用zip,我们可能只能放弃迭代器回到传统的下标遍历的模式了。这样当然是可以的,不过有两个小问题,第一个小问题当然是代码的可读性变差了,不够pythonic,第二个问题是我们需要维护两个容器长度不一样的情况,会增加额外的代码。而使用zip,可以同时解决以上两个问题。

    我们来看一个例子:

    最后输出的结果是人名和职业的tuple:

    xiaoming coach
    xiaohua student
    xiaohei student
    xiaoli student
    

    在上面的示例中,名称和作业的长度实际上不一致。使用zip时,它会根据较短的zip自动为我们截断。如果我们不想截断它,也可以在itertools下使用zip[最长]而不是zip:

    from itertools import zip_longest
    for name, job in zip_longest(names, jobs):
    

    这样,长度不足的元素将填充为“无”。Zip﹣length提供了一个参数fillvalue,可以用我们指定的值填充它。

    无论是Zip还是Zip﹣long EST,它都可以支持多个迭代器的遍历。例如:

     Zip不仅便于我们迭代,而且便于我们生成dict。例如,在刚才的例子中,如果我们想生成一个名称和职业的dict,一般的方法是先定义一个dict,然后遍历所有键和值来生成一个dict。但是,使用Zip,我们可以将这个操作简化为一行代码:

    jobDict = dict(zip(names, jobs))
    

    需要注意的是,我们调用zip的结果实际上是一个迭代器。当我们将其转换为dict时,我们会自动遍历迭代器的内容。例如,如果直接打印zip调用的结果,我们会发现屏幕上的输出是迭代器的地址:

    print(zip(names, jobs))
    >>> <zip object at 0x10ec93b40>

    我们想要获得它的内容,需要将它手动转成list:

    print(list(zip(names, jobs)))
    >>> [('xiaoming', 'coach'), ('xiaohua', 'student'), ('xiaohei', 'student'), ('xiaoli', 'student')]

    实际上,枚举和zip的底层都是基于迭代器实现的。原则上,没有深刻的内容,我们也不使用它们来编写代码。但Python之所以是Python,以及为什么许多人称之为简明语言和逻辑,是因为我们广泛使用这些工具和方法来简化代码逻辑。所以我们很有必要去理解它。我希望每个人都能写出Python IC的代码,Python IC不仅在编写代码方面很强大,而且本身也很漂亮。

  • 相关阅读:
    条件概率和链式法则 conditional probability & chain rule
    如何训练一个神经网络?
    高斯贝叶斯分类器
    LDA
    机器学习中的数学-线性判别分析(LDA)
    理解矩阵
    pca数学原理(转)
    SVM入门
    Top 10 Machine Learning Algorithms For Beginners
    vfp
  • 原文地址:https://www.cnblogs.com/lyck/p/12558745.html
Copyright © 2011-2022 走看看