python優勢之通過一段代碼來了解python的強大之處

晚上閒暇之餘隨意翻了一下博客,看到https://www.jianshu.com/p/69bf0ed0b5cc作者提到了一段代碼,剛開始看沒啥感覺,仔細深入後引起了我的注意。裏面使用了python最簡單的語法,確產生了最神奇的效果,代碼的世界太神奇了!先貼一下源碼吧
1、什麼是可變參數,什麼是關鍵字參數
2、使用了什麼基礎的python語法
3、爲什麼這段代碼能引起我的注意

def transfer_kwargs(*args):
    kwargs = {}
    for arg in args:
        k, v = map(lambda x: x.strip(), arg.split('.', 1))
        if '.' in v:
            item = kwargs.setdefault(k, {})  # step1
            values = v.split('.')
            for j in values[:-2]:
                item = item.setdefault(j, {})  # step2
            item[values[-2]] = values[-1]  # step3
        else:
            kwargs.update({k: v})
    print(kwargs)
if __name__ == '__main__':
    info1 = '1.2.3.4.5'
    info2 = 'a.b.c.d.f'
    transfer_kwargs(info1, info2)
輸出:
>>>{'1': {'2': {'3': {'4': '5'}}}, 'a': {'b': {'c': {'d': 'f'}}}}

這段代碼總共13行代碼,確實現了複雜的功能,將簡單的字符複雜化,當然也有其他的方法可以實現這種功能,本文就此函數進行一個概要的分析:

1、什麼是可變參數,什麼是關鍵字參數

*args是可變參數,args接收的是一個tuple;使用了可變參數入參,使的入參變量可以多個。如我們可以這樣運行函數

if __name__ == '__main__':
    info1 = '1.2.3.4.5'
    info2 = 'a.b.c.d.f'
    info3 = 'e.f.g.h.i.j.k'
    info4 = 'a1.b1.c1.d1.f1'
    transfer_kwargs(info1, info2,info3, info4)
輸出:
>>>{'a': {'b': {'c': {'d': 'f'}}}, '1': {'2': {'3': {'4': '5'}}}, 'a1': {'b1': {'c1': {'d1': 'f1'}}}, 'e': {'f': {'g': {'h': {'i': {'j': 'k'}}}}}}

說到可變參數,就不得提一下關鍵字參數;**kwargs是關鍵字參數,kwargs接收的是一個dict,入參內容可以實現擴大化,可變參數加關鍵字參數入參=萬能參數,此處不再累述。

2、使用了什麼基礎的python語法

2.1 map(function, iterable, …)

map() 會根據提供的函數對指定序列做映射。
第一個參數 function 以參數序列中的每一個元素調用 function 函數,返回包含每次 function 函數返回值的新列表。實例如下:

>>>def square(x) :            # 計算平方數
...     return x ** 2
... 
>>> map(square, [1,2,3,4,5])   # 計算列表各個元素的平方
[1, 4, 9, 16, 25]
>>> map(lambda x: x ** 2, [1, 2, 3, 4, 5])  # 使用 lambda 匿名函數
[1, 4, 9, 16, 25]
 
# 提供了兩個列表,對相同位置的列表數據進行相加
>>> map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])
[3, 7, 11, 15, 19]

2.2 lambda [arg1 [,arg2,…argn]]:expression

python的匿名函數,lambda只是一個表達式,函數體比def簡單很多;lambda的主體是一個表達式,而不是一個代碼塊。僅僅能在lambda表達式中封裝有限的邏輯進去;lambda函數擁有自己的命名空間,且不能訪問自有參數列表之外或全局命名空間裏的參數;雖然lambda函數看起來只能寫一行,卻不等同於C或C++的內聯函數,後者的目的是調用小函數時不佔用棧內存從而增加運行效率,實例如下:

#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
# 可寫函數說明
sum = lambda arg1, arg2: arg1 + arg2;
 
# 調用sum函數
print ("相加後的值爲 : ", sum( 10, 20 ))
print ("相加後的值爲 : ", sum( 20, 20 ))
輸出結果:
相加後的值爲 :  30
相加後的值爲 :  40

2.3 str.strip([chars])

Python strip() 方法用於移除字符串頭尾指定的字符(默認爲空格或換行符)或字符序列;該方法只能刪除開頭或是結尾的字符,不能刪除中間部分的字符,實例如下:

#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
str = "00000003210Runoob01230000000"; 
print str.strip( '0' );  # 去除首尾字符 0
 
 
str2 = "   Runoob      ";   # 去除首尾空格
print (str2.strip());
輸出結果:
3210Runoob0123
Runoob

2.4 str.split(str="", num=string.count(str)).

Python split() 通過指定分隔符對字符串進行切片,如果參數 num 有指定值,則分隔 num+1 個子字符串。實例如下:

#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
txt = "Google#Runoob#Taobao#Facebook"
 
# 第二個參數爲 1,返回兩個參數列表
x = txt.split("#", 1)
 
print(x)
輸出結果:
['Google', 'Runoob#Taobao#Facebook']

2.5 dict.setdefault(key, default=None)

Python 字典 setdefault() 函數和 get()方法 類似, 如果鍵不存在於字典中,將會添加鍵並將值設爲默認值;這兩種方法有什麼區別呢,看實例:

if __name__ == '__main__':
    info5 ={'age': 18, 'name': 'Jack'}
    info6 = {'age': 18, 'name': 'Jack'}
    print(info5.get("sex",'男'))
    print(info6.setdefault("sex",'男'))
    print(info5)
    print(info6)
以上實例輸出結果爲:
男
男
{'age': 18, 'name': 'Jack'}
{'age': 18, 'name': 'Jack', 'sex': '男'}

通過實例可以發現dict.setdefault(key, default=None)使用取出一個不存在的鍵的值(返回默認鍵的值,並且將新的鍵值保存在字典中)

2.6 values[:-2]

values[start🔚step],其中start:起始索引,從0開始,-1表示結束;end:結束索引;step:步長,end-start,步長爲正時,從左向右取值。步長爲負時,反向取值。注意切片的結果不包含結束索引,即不包含最後的一位,-1代表列表的最後一個位置索引。
values[:-2]默認起始位置爲0,步長爲1,結束索引爲倒數第二個字符。實例如下:

if __name__ == "__main__":
    a = [1,2,3,4,5]
    print(a[:-2])
輸出結果爲:
[1, 2, 3]

3、爲什麼這段代碼能引起我的注意

整段代碼主要是對一定秩序的字符串做稍微的嵌套處理,如效果:

if __name__ == '__main__':
    info1 = '1.2.3.4.5'
    info2 = 'a.b.c.d.f'
    transfer_kwargs(info1, info2)
    輸出結果:
    {'1': {'2': {'3': {'4': '5'}}}, 'a': {'b': {'c': {'d': 'f'}}}}

函數體內有一串封尾代碼,item[values[-2]] = values[-1],去除這段代碼後的結果爲

{'1': {'2': {'3': {}}}, 'a': {'b': {'c': {}}}}

換句話說函數體的其他部分主要實現的是嵌套功能,遍歷列表(排除最後一個值,這個值是用來最後面的封尾處理的字典建4或c的值)。這種簡單的嵌套,使的最開始時每個字典的key對應的值是{}。直到結尾的4和c對應的值是5和d。

            for j in values[:-2]:
                item = item.setdefault(j, {})

分析到這一步了相信大家都能將代碼看懂,就不過多累述了,在對這段代碼的分析後我找到以下這麼幾點,作爲吸引我的關鍵所在:
1 python的一個簡單語法可以實現很多複雜操作,而多個簡單語法混合可以達到奇妙的效果。如本文提及到的函數。
2 整段代碼沒有任何的冗餘,夾雜着循壞語句、條件語句恰到好處的實現了複雜的功能。
3 擴展了一些基本語法的知識item.setdefault(j, {})這個方法第一次看到,完美解決了在get語法上的缺陷

python代碼,因簡單而複雜
基礎語法2實例引用自菜鳥教程

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章