美文网首页清风Python
一道简单的Python面试题,却涵盖诸多考点,快来试试吧!

一道简单的Python面试题,却涵盖诸多考点,快来试试吧!

作者: 清风Python | 来源:发表于2020-11-05 00:06 被阅读0次

    晚上翻手机,看见一道网友发的python面试题求助帖,当时简单扫一眼就跳过了,但下来仔细想想觉得还蛮有趣,开电脑梳理下思路,因为没有官方答案,所以大家可以一起来做做,其中涉及的python知识点还是蛮多的。

    题目内容

    一个标准的版本需要涵盖,大版本.小版本.补丁版,各版本之间使用英文点符号分隔,且每个版本取值范围均为0~99。

    现有一批产品版本号列表,需要过滤掉不符合要求的内容后,将版本号通过sorted进行升序排列。

    题目分析

    初看此题,给人的感觉有些好笑,居然要告诉大家使用sorted进行排序,难道是生怕谁不知道这个函数吗?

    但当随便验证两个用例发现,sorted的默认排序存在BUG。

    sorted(['1.3.0','1.1.0','1.2.0'])
    >>> ['1.1.0', '1.2.0', '1.3.0']
    # 错误的默认排序
    sorted(['1.30.0','1.4.0','1.2.0'])
    >>> ['1.2.0', '1.30.0', '1.4.0']
    

    直接使用字符串进行排序,默认是按位对比每个版本号,然后进行排序,这导致了1.30.0 < 1.4.0的BUG。

    仔细想想,面试官想考察的应该是sorted的自定义排序方法。那么该如何正确的比较所有版本号,又能同时过滤掉错误的版本号呢?

    过滤版本号

    考虑到版本号的特殊性,最简单的过滤方法,必然是正则了:

    import re
    pattern = re.compile(r'^[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}')
        if not pattern.match(version):
            raise ValueError("error version [%s],the version type must be [xx.xx.xx]" % version)
    

    当然这里是我们验证的操作方式,排序时当然不能抛出异常了。

    版本号比较

    既然每个版本号的取值范围在0-99之间,那么熟悉数学的我们,是否有了思路?我们按照百进制的方式,来统计版本号,不就能轻易的达到目的么?就拿刚才的1.30.0和1.4.0来举例如下:

    版本号 大版本(10000) 小版本(100) 补丁版本(1) 总计
    1.30.0 10000 3000 0 13000
    1.4.0 10000 400 0 10400
    2.1.0 20000 100 0 20100

    最终代码

    # -*- coding: utf-8 -*-
    # @微信号   : King_Uranus
    # @公众号    : 清风Python
    # @GitHub   : https://github.com/BreezePython
    # @Date     : 2020/11/04 22:48:33
    # @Software : PyCharm
    # @version  :Python 3.7.8
    # @File     : compare_version.py
    import re
    
    class CompareVersion:
        def __init__(self, version_list):
            self.versions = version_list
            self.error_version_num = 0
    
        def com_version(self, version):
            sum_version = 0
            version_weights = [10000, 100, 1]
            pattern = re.compile(r'^[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}')
            if not pattern.match(version):
                self.error_version_num += 1
                return -1
            version_list = version.split('.')
            for index, small_version in enumerate(version_list):
                sum_version += version_weights[index] * int(small_version)
            return sum_version
    
        def sort_version(self):
            sorted_version = sorted(self.versions, key=lambda x: self.com_version(x))
            return sorted_version[self.error_version_num:]
    
    
    if __name__ == '__main__':
        versions = ['0.0.0', '99.99.99', '100.0.1', '1.0.-1', '1.1.99',
                    '2.10.1', '2.9.10', '999', '10-0.1']
        main_class = CompareVersion(versions)
        print(main_class.sort_version())
    
    output:
    ['0.0.0', '1.1.99', '2.9.10', '2.10.1', '99.99.99']
    

    在sorted遍历过程中,每当发现一个错误版本号,我们就将error_version_num加一,并返回-1,这样当最终排序后,将切片的排序结果返回,就达到了最终的目的。

    当然了,这只是我一时兴起的抛砖引玉答案,期待大家给出更好的作答。

    The End

    期待你关注我的公众号清风Python,如果你觉得不错,希望能动动手指转发给你身边的朋友们。
    我的github地址:https://github.com/BreezePython

    相关文章

      网友评论

        本文标题:一道简单的Python面试题,却涵盖诸多考点,快来试试吧!

        本文链接:https://www.haomeiwen.com/subject/uvonvktx.html