從零開始學Python-day5

Python--Day5

學習要有定位,明確目標地去學習。希望自己能堅持下去,並有所收穫---leaves


python04 -- python基礎知識總結以及函數進階



一、python中獲取幫助

    python中獲取幫助的方法有兩種:

     1.dir("數據類型") ===>看所有方法

    2.help("數據類型或者方法") ===>查看官方文檔

##代碼舉例:


##dir()

>>> dir([])

['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__',

 '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', 

 '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', 

 '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', 

 '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__',

  '__setslice__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'count',

   'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']


##help()

help([].append)

Help on built-in function append:


append(...)

    L.append(object) -- append object to end


二、字典的高階用法

   常用字典的兩種高階用法dict.get()和dict.setdefault()


   1.dict.get()    ==>主要作用是獲取key對應的value值,若字典中無該key值則以給定的value賦予該key.且字典新增一對key,value值。


   2.dict.setdefault() ===>主要針對不存在的key設置默認值

##代碼舉例如下:


##dict.get()用法

In [9]: d = {"192.168":1}

In [10]: str = "192.168.1"

In [11]: d[str] = d.get(str,0)+1

In [12]: d

Out[12]: {'192.168': 1, '192.168.1': 1}

In [13]: str = "192.168"

In [14]: d[str] = d.get(str,0)+1

In [15]: d

Out[15]: {'192.168': 2, '192.168.1': 1}


##dict.setdefault()

for k ,v in res.items():

new.setdefault(v,[])

new[v].append(k)


三、list和dict的區別及相互之間的轉換


3.1 list和dict的區別


相同點:都可以存儲各種數據結構,可以嵌套

不同點:

    list 有序

        查找需要遍歷,速度慢


    dict 沒順序

        查找非常迅速


3.2 list和dict的轉換


    dict--->list    用items函數

    list --->dict  enumerate() 或者使用dict.fromkeys()函數

##具體代碼如下:

##dict--->list 

In [17]: d.items()

Out[17]: [('192.168', 2), ('192.168.1', 1)]


##list --->dict 


##enumerate()

In [18]: l = list("hello")

In [19]: print dict((k,v) for k ,v in enumerate(l))

{0: 'h', 1: 'e', 2: 'l', 3: 'l', 4: 'o'}


##fromkeys()的用法

In [53]: d.fromkeys([1,2,3])

Out[53]: {1: None, 2: None, 3: None}

In [54]: d.fromkeys(['name','age'])

Out[54]: {'age': None, 'name': None}

In [55]: d

Out[55]: {'age': 12, 'name': 'test'}

In [56]: d.fromkeys(['one','two'],['1','2'])

Out[56]: {'one': ['1', '2'], 'two': ['1', '2']}

In [57]: d

Out[57]: {'age': 12, 'name': 'test'}

In [58]: d.fromkeys(d,['1','2'])

Out[58]: {'age': ['1', '2'], 'name': ['1', '2']}

In [59]: d

Out[59]: {'age': 12, 'name': 'test'}

In [60]: {}.fromkeys(d,[1,2,3])

Out[60]: {'age': [1, 2, 3], 'name': [1, 2, 3]}


四、文件的處理


4.1 python中文件的打開方式


    方法一:        

        f = open("a.txt")

        f.read()

        f.close()##這個模式操作文件要記得關閉文件,即一定有f.close()

    

    方法二:

         with open('a.txt') as f:  

            f.read()

        ###注意該方法提供了自動關閉文件的功能

        ###with可以同時打開多個文件

        

##使用with打開多個文件


#方法一:

with open('file1') as f1:

    with open('file2') as f2:

        with open('file3') as f3:

            for i in f1:

                j = f2.readline()

                k = f3.readline()

                print(i,j,k)


#方法二:較爲優雅

with open('file1') as f1, open('file2') as f2, open('file3') as f3:

    for i in f1:

        j = f2.readline()

        k = f3.readline()

        print(i,j,k)

        


##方法三:通過contextlib模塊的

from contextlib import nested


with nested(open('file1'), open('file2'), open('file3')) as (f1,f2,f3):

    for i in f1:

        j = f2.readline()

        k = f3.readline()

        print(i,j,k)


4.2 文件的操作


    1.文件剛打開,指針在開始的地方,每次read ,readline ,readlines都會把指針移動到讀取數據的地方

    2.seek() f.seek(0)#把指針移到文件開始

    3.tell() f.tell() #返回指針所在的位置


4.3 文件的注意事項

    

#'a'模式,每次都是從文件尾開始追加數據

#注意文件的'w'模式,打開文件的時候就清空文件了。


#打開大文件推薦使用readline()函數 或者for  line  in f

files.read() 每次讀取整個文件 read可以傳一個數字,表示讀多少個字符。不傳就是讀整個文件

files.readline()每隻讀取文件的一行

files.readlines()每次按行讀取整個文件內容,一次全部讀取文件


五、python其它基礎知識


5.1 元組


  元組:元組也可以嵌套任意類型的數據結構,但是元組不能修改,定義後不可改變,正是由於這種特性,元組這種數據類型可以作爲字典的key,在nginx日誌分析中用來統計多個維度(ip,url,code)等等。



5.2 遍歷list的方法   


    1.直接遍歷列表  for i   in  list  

    2. 根據索引值遍歷  range()配合長度

    3. 高階遍歷方法同時獲取索引值和值

    In [18]: for k ,v in enumerate(['one','two','three']):

       ...:     print k , v

 

    0 one

    1 two

    2 three


5.3 遍歷dict的方法(目前只有一種方法)


    for  k ,v in dict.items():

        print k ,v



六、函數


    函數的定義:簡單的理解就是一次執行很多行代碼

    格式:當前def縮進模塊中的所有內容都是函數內容

    def 函數名(參數):

        函數內容


6.1 簡單的函數舉例


##python中簡單的函數

In [13]: def hello():

    ...:     print "hello world"

    ...:     print "hi Bob"

    ...:     

In [14]: hello()

hello world

hi Bob


6.2 函數的返回值


###函數的返回值:定義,即爲函數執行後的狀態結果,與shell中的echo $?相等

print   hanshu   ==>函數功能、方法

print   hanshu() ===>函數的返回值


##代碼練習

##定義函數hello()

In [15]: def hello():

    ...:     print "hello world"

    ...:     print "hi Bob"

    ...:     return '2016'

    ...: 


##直接print+函數名  的結果 ===>返回結果爲對象

In [16]: print hello

<function hello at 0xb6a4dfb4>


##print + 函數名()  的結果 ===>返回函數的執行狀態結果

In [17]: print hello()

hello world

hi Bob

2016


6.3 函數的參數


    python中函數參數的種類1.必備參數  2.關鍵字參數  3.缺省值參數

    1.必備參數:調用函數時,必須以正確的順序傳入,並且傳入的參數必須與聲明的參數一致,否則可能出現錯誤參數調用的情況。


    2.關鍵字參數:關鍵字參數和函數調用關係緊密,函數調用使用關鍵字參數來確傳入的參數值,使用關鍵字參數允許調用函數時參數的順序和聲明的時候不一致,因爲python解釋器能夠用參數名匹配參數值。關鍵字參數的優點就是===>可讀性好


    3.缺省值參數:調用函數時,如果缺省值參數沒有傳入的話,就是用預先定義的默認值。


###帶參數的函數練習

##函數參數之一:必備參數 

In [20]: def hello(name,age):

    ...:     print "hello %s,you age is %s" %(name,age)

    ...:     return '2016'

    ...:     

    ...: 

In [21]: hello('test',13)

hello test,you age is 13

Out[21]: '2016'  <===out輸出爲函數的執行狀態結果



##函數小練習==>寫一個階乘的函數

In [22]: def jiecheng(num):

    ...:     res = 1

    ...:     while num > 0:

    ...:         res *= num

    ...:         num -= 1 

    ...:     return res

    ...: 

In [23]: jiecheng(3)

Out[23]: 6

In [24]: jiecheng(4)

Out[24]: 24


##函數參數之二:關鍵字參數

In [25]: def hello(name='aaa',age=12):

    ...:     print "hello %s,you age is %s" %(name,age)

    ...:     return '2016'

    ...:     

    ...: 

In [26]: 

In [26]: hello(age=14,name='ccc')

hello ccc,you age is 14

Out[26]: '2016'



##函數參數之三:缺省值參數

In [25]: def hello(name='aaa',age=12):

    ...:     print "hello %s,you age is %s" %(name,age)

    ...:     return '2016'

    ...:     

    ...: 

In [26]: 

In [26]: hello(name='ccc')

hello ccc,you age is 14

Out[26]: '2016'


特殊參數情況:

    當函數希望收集不定長的參數時,即參數的個數不確定,則使用星號(*)來收集參數。星號(*)收集函數前邊固定參數後剩下的所有參數。

    若函數收集的關鍵字參數也是個數不確定的話,則使用兩個星號(**)來收集參數。


##特殊參數的代碼詳情


##一個星號(*)收集不定長參數


##情況一:注意*號收集前邊參數收集後剩下的所有的參數

In [1]: def test(name,*num):

   ...:     print num

In [2]: test(1,2,3,4,5)

(2, 3, 4, 5)


##情況二:收集所有的參數

n [28]: def add_all(*num):

    ...:     sum = 0 

    ...:     for i in num:

    ...:         sum += i

    ...:     return sum

    ...: 

In [29]: add_all(1,2,3)

Out[29]: 6

In [30]: add_all(1,2,3,4,5,6)

Out[30]: 21



##兩個星號(**)收集關鍵字的參數

##(**)開頭  ,收集關鍵字參數

In [31]: def test(**arr):

    ...:     print arr

In [34]: test(name='aa',age=15)

{'age': 15, 'name': 'aa'}


6.4 函數的進階,使用函數優化之前的單詞統計代碼


    python的核心思想是函數化編程,所以函數式拆分代碼需要注意;儘量避免全局變量,儘量減少函數間的練習,提高函數的可讀性。程序是給人讀的。


###拆分代碼爲函數的注意事項:儘量避免全局變量

本人拆分統計單詞讀寫文件的代碼如下:

#coding:utf-8

res = {'!': 1, '.': 1, 'Bob': 1, 'I': 2, 'a': 1, 'am': 2, 'boy': 1}

new = {}

for k ,v in res.items():

new.setdefault(v,[])

new[v].append(k)

print new

#keys = max(new)

#print "%s  ----> %s" %(keys,new[keys])

def op_file(filename,mode='r'):

f = open(filename,mode)

str = "/usr/local/src/newbie/03==>result\n<table border='1px'>\

       <tr><th>times</th><th>word</th></tr>"

while True:

keys = max(new)

for i in new[keys]:

str += "<tr><td>%s</td><td>%s</td></tr>" %(keys,i)

new.pop(keys)

if len(new) == 0 :

break

str += "</table>\n"

if ('w' in mode) or ('a' in mode) : ##使用in來判斷模式是否爲寫模式

f.write(str)

f.close()

op_file(filename='/var/www/html/tongji.html',mode="w+")


6.5 變量的作用域


    講到函數不得不引申下變量的作用域問題,一般編程語言中變量都分爲全局變量和局部變量。具體定義自己可以百度瞭解些許,此處一帶而過,python中全局變量使用關鍵詞global來定義,一般在函數內部定義全局變量。


##global定義全局變量

[root@xiaowei 04]# cat a.py 

num = 3

def hello():

global num 

num = 5

print num

print hello()

print "num = %s" %num

[root@xiaowei 04]# python a.py 

5

None

num = 5



七、python語言中關於排序的進階


    簡而言之,冒泡排序、插入排序等一系列算法僅僅是編程語言的基礎原理,而在python中可以通過簡單的一兩行代碼實現複雜數據結構的排序。接下來將一步一步深入python排序原理及通間易讀代碼的實現。


7.1 以nginx日誌統計完ip後得到的結果字典爲例 

 

res = {'111.85.41.230': 103, '218.200.66.197': 21, '218.200.66.196': 14, '221.176.5.153': 31, '218.200.66.199': 19, '218.200.66.198': 25, '221.176.5.156': 3, '10.35.1.82': 61, '221.176.5.154': 3, '220.181.125.177': 1, '101.227.4.33': 2, '220.172.215.69': 1}


思路有兩種:

    1.將字典翻轉,即以出現的次數爲key,value值爲ip,但是需要注意的時這種情況,需要將ip存放到事先準備的空列表中去,否則key爲ip出現次數的話,若有兩個ip出現次數相同,那麼會出現值被覆蓋的情況從而使結果有所偏差。翻轉後使用max(dict)取出最大次數的value值列表,拼接成html網頁元素,然後dict.pop(keys)去掉最大值的key以此輪訓依次出現最大ip的情況。---By  Panda

    

    2.上述res字典可以通過用dict.items()將res字典轉換爲元組組成的列表,然後通過對列表中每個元素中代表次數的項進行排序。然後根據排序結果拼接html元素。--By woniiu


接下來主要深入woniu的思想爲主線從而引出最終主人公python自帶的sorted()函數。


7.1.1 冒泡法實現排序:


tmp = res.items()

tmp = [('218.200.66.197', 21), ('218.200.66.196', 14), ('218.200.66.199', 19), \

    ('218.200.66.198', 25), ('101.227.4.33', 2), ('111.85.41.230', 103), \

    ('220.181.125.177' , 1), ('220.172.215.69', 1),('221.176.5.153', 31), \

    ('221.176.5.156', 3), ('10.35.1.82', 61), ('221.176.5.154', 3)]

##原始的冒泡排序代碼:

d = {'10.35.1.82': 61, '101.227.4.33': 2, '111.85.41.230': 103,'218.200.66.196': 14,\

    '218.200.66.197': 21,'218.200.66.198': 25,'218.200.66.199': 19,'220.172.215.69': 1,\

    '220.181.125.177': 1,'221.176.5.153': 31,'221.176.5.154': 3,'221.176.5.156': 3}

    

tmp = d.items()

print tmp

le = len(tmp)

for i in range(le-1):

        for j in range(le-1-i):

                if tmp[j][1] < tmp[j+1][1]:

                        tmp[j],tmp[j+1] = tmp[j+1],tmp[j]

print "sorted tmp :%s" %tmp


##排序後通過切片獲取自己想要打印的數據。

tmp = tmp[:3]

for i in tmp:

        print "ip is %s ,count is %s" %i



7.1.2 通過函數方法實現冒泡排序;

用函數實現冒泡排序bubble_sort() 

###代碼:

def bubble_sort(tmp,le,num=3):

        for i in range(le-1):

                for j in range(le-1-i):

                        if tmp[j][1] < tmp[j+1][1]:

                                tmp[j],tmp[j+1] = tmp[j+1],tmp[j]

        tmp = tmp[:num]

        return tmp

le = len(tmp)

res = bubble_sort(tmp,le,num=4)


7.3 函數的進階


    ###進階排序函數===>函數可以當作參數傳遞給另一個函數


具體實現代碼如下:


##以函數爲參數傳遞給函數


[root@xiaowei sorted]# cat sort_fn.py 

#coding:utf-8

##原始數據

arr = [1,3,65,2,6,32,0,7,14]


##列表嵌套元組

arr2 = [('xiaohong',90),('xiaohua',58),('xiaohei',100)]


##列表嵌套字典

d = [{'name':'xiaohong','age':18},{'name':'xiaohei','age':10},{'name':'xiaowang','age':33}]


def sort_fn1(data): ##取出需要排序的元素(針對原始數據)

return data 


def sort_fn2(data): ##取出需要排序的元素(針對列表)

return data[1] 


def sort_fn3(data): ##取出需要排序的元素(針對字典)

return data['age'] 


##自己定義的排序函數

def my_sort(arr,sort_fn1):

for j in range(len(arr)-1):

for i in range(len(arr)-1):

if sort_fn1(arr[i]) >sort_fn1(arr[i+1]):

arr[i],arr[i+1]=arr[i+1],arr[i]

return arr


##對原始數據進行排序

print my_sort(arr,sort_fn1)


##對列表嵌套元組進行排序

print my_sort(arr2,sort_fn2)


##對列表嵌套字典進行排序

print my_sort(d,sort_fn3)



[r[root@xiaowei sorted]# python sort_fn.py 

##原始數據的排序結果

[0, 1, 2, 3, 6, 7, 14, 32, 65]


##列表嵌套元組的排序結果

[('xiaohua', 58), ('xiaohong', 90), ('xiaohei', 100)]


##列表嵌套字典的排序結果

[{'age': 10, 'name': 'xiaohei'}, {'age': 18, 'name': 'xiaohong'}, {'age': 33, 'name': 'xiaowang'}]

Noneoot@xiaowei sorted]#




7.4 最終大招--python自帶的sorted()函數排序


    sorted()函數的格式如下:

     僞代碼格式:    sorted(需要排序的列表,排序的元素)

     編碼  格式:    sorted(arr,key=函數)


###使用python自帶的sorted函數代碼


##代碼示例


[root@xiaowei sorted]# cat sorted.py

arr = [1,3,65,2,6,32,0,7,14]


def sort_fn1(data):

        return data

def sort_fn2(data):

        return data[1]

def sort_fn3(data):

        return data['age']

        

print sorted(arr,key=sort_fn1)


arr2 = [('xiaohong',90),('xiaohua',58),('xiaohei',100)]


print sorted(arr2,key=sort_fn2)


d = [{'name':'xiaohong','age':18},{'name':'xiaohei','age':10},{'name':'xiaowang','age':33}]


print sorted(d,key=sort_fn3)


##執行結果如下:

[root@xiaowei sorted]#

[root@xiaowei sorted]# python sorted.py 

[0, 1, 2, 3, 6, 7, 14, 32, 65]

[('xiaohua', 58), ('xiaohong', 90), ('xiaohei', 100)]

[{'age': 10, 'name': 'xiaohei'}, {'age': 18, 'name': 'xiaohong'}, {'age': 33, 'name': 'xiaowang'}]



7.5 python函數必備高階技能之---lambda匿名函數


    lambda匿名函數的定義:特別簡單的、沒有名字的函數,僅有函數return返回值的函數。


###lambda函數舉例


##lambda代碼舉例===>用於簡寫,簡潔代碼


In [13]: hello = lambda x:x

In [14]: print hello([1,2,3])

[1, 2, 3]


In [15]: hello = lambda x:x[2]

In [16]: print hello([1,2,3])

3


7.6 sorted()函數 + lambda匿名函數 終極通間易讀實現排序


####思路就是將sorted()函數的key用lambda來定義

##代碼舉例

[root@xiaowei sorted]# cat ver.py 

arr = [1,3,2,78,21,32,55,0,9]


arr2 = [('xiaohong',90),('xiaohua',58),('xiaohei',100)]


d = [{'name':'xiaohong','age':18},{'name':'xiaohei','age':10},{'name':'xiaowang','age':33}]


print sorted(arr,key=lambda x:x)###使用lambda來獲取排序的對象


print sorted(arr2,key=lambda x:x[1])###使用lambda來獲取排序的對象


print sorted(d,key=lambda x:x['age'])###使用lambda來獲取排序的對象


###排序結果展示

[root@xiaowei sorted]# python ver.py 

[0, 1, 2, 3, 9, 21, 32, 55, 78]


[('xiaohua', 58), ('xiaohong', 90), ('xiaohei', 100)]


[{'age': 10, 'name': 'xiaohei'}, {'age': 18, 'name': 'xiaohong'}, {'age': 33, 'name': 'xiaowang'}]


7.7 nginx日誌處理的最終優化代碼

  https://github.com/Fuliwei/newbie/blob/master/04/ketang/test.py(最終代碼在辛苦移步github)


###統計nginx日誌最終進階:

##排序時使用sorted()+lambda以快速實現

###統計ip以及出現次數排序的代碼優化

[root@xiaowei ketang]# cat test.py 

#/usr/bin/python

#coding:utf-8


def htmlStr(arr):

        html_str = "<html><h4>/usr/local/src/newbie/04/ketang/test.py ====>result[test.html]<h4>\n<table border='1px'>\n<tr><th>%s</th><th>%s</th><th>%s</th></tr>\n" %('Count','IP','URL')

        for i in arr:

                html_str += "<tr><td>%s</td><td>%s</td><td>%s</td></tr>\n" %(i[1],i[0][0],i[0][1])


        html_str += "</table></html>\n"

        return html_str


def operateFile(filename,mode='r',string=''):

        if ('w' in mode) or ('a' in mode):

                with open(filename,'w') as files:

                        files.write(string)

                return 'Write OK'

        else:

                res = {}

                with open(filename) as files:

                        for line in files:

                                #print line 

                                line = line.strip('\n').split(' ')

                                #print line

                                tmp = (line[0],line[6])#,line[8])

                                res[tmp] = res.get(tmp,0)+1

                                #print "res is %s" %res

                        return sorted(res.items(),key=lambda x:x[1],reverse = True)


test = operateFile('log.log')

test = test[:10]

htmlstr = htmlStr(test)


print operateFile('/var/www/html/test.html',mode='w',string=htmlstr)



--end Thx.


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