一道簡(jiǎn)單的Python面試題,卻涵蓋諸多考點(diǎn),快來試試吧!

晚上翻手機(jī),看見一道網(wǎng)友發(fā)的python面試題求助帖,當(dāng)時(shí)簡(jiǎn)單掃一眼就跳過了,但下來仔細(xì)想想覺得還蠻有趣,開電腦梳理下思路,因?yàn)闆]有官方答案,所以大家可以一起來做做,其中涉及的python知識(shí)點(diǎn)還是蠻多的。

題目?jī)?nèi)容

一個(gè)標(biāo)準(zhǔn)的版本需要涵蓋,大版本.小版本.補(bǔ)丁版,各版本之間使用英文點(diǎn)符號(hào)分隔,且每個(gè)版本取值范圍均為0~99。

現(xiàn)有一批產(chǎn)品版本號(hào)列表,需要過濾掉不符合要求的內(nèi)容后,將版本號(hào)通過sorted進(jìn)行升序排列。

題目分析

初看此題,給人的感覺有些好笑,居然要告訴大家使用sorted進(jìn)行排序,難道是生怕誰不知道這個(gè)函數(shù)嗎?

但當(dāng)隨便驗(yàn)證兩個(gè)用例發(fā)現(xiàn),sorted的默認(rèn)排序存在BUG。

sorted(['1.3.0','1.1.0','1.2.0'])
>>> ['1.1.0', '1.2.0', '1.3.0']
# 錯(cuò)誤的默認(rèn)排序
sorted(['1.30.0','1.4.0','1.2.0'])
>>> ['1.2.0', '1.30.0', '1.4.0']

直接使用字符串進(jìn)行排序,默認(rèn)是按位對(duì)比每個(gè)版本號(hào),然后進(jìn)行排序,這導(dǎo)致了1.30.0 < 1.4.0的BUG。

仔細(xì)想想,面試官想考察的應(yīng)該是sorted的自定義排序方法。那么該如何正確的比較所有版本號(hào),又能同時(shí)過濾掉錯(cuò)誤的版本號(hào)呢?

過濾版本號(hào)

考慮到版本號(hào)的特殊性,最簡(jiǎn)單的過濾方法,必然是正則了:

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)

當(dāng)然這里是我們驗(yàn)證的操作方式,排序時(shí)當(dāng)然不能拋出異常了。

版本號(hào)比較

既然每個(gè)版本號(hào)的取值范圍在0-99之間,那么熟悉數(shù)學(xué)的我們,是否有了思路?我們按照百進(jìn)制的方式,來統(tǒng)計(jì)版本號(hào),不就能輕易的達(dá)到目的么?就拿剛才的1.30.0和1.4.0來舉例如下:

版本號(hào) 大版本(10000) 小版本(100) 補(bǔ)丁版本(1) 總計(jì)
1.30.0 10000 3000 0 13000
1.4.0 10000 400 0 10400
2.1.0 20000 100 0 20100

最終代碼

# -*- coding: utf-8 -*-
# @微信號(hào)   : King_Uranus
# @公眾號(hào)    : 清風(fēng)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遍歷過程中,每當(dāng)發(fā)現(xiàn)一個(gè)錯(cuò)誤版本號(hào),我們就將error_version_num加一,并返回-1,這樣當(dāng)最終排序后,將切片的排序結(jié)果返回,就達(dá)到了最終的目的。

當(dāng)然了,這只是我一時(shí)興起的拋磚引玉答案,期待大家給出更好的作答。

The End

期待你關(guān)注我的公眾號(hào)清風(fēng)Python,如果你覺得不錯(cuò),希望能動(dòng)動(dòng)手指轉(zhuǎn)發(fā)給你身邊的朋友們。
我的github地址:https://github.com/BreezePython

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容