Python 內置對象及模塊 map zip lambda yield

Python作为一種高效的腳本語言,內置了很多實用的函數,同時也提供了豐富的工具模塊。 下面是總結的幾種內置對象及函數的應用技巧。

 1、強大的列表解析功能

  • 對列表元素的簡單操作:例如將列表的每個元素乘以2
    list1 = [1,2,3,4]
    list1 = [x*2 for x in list1]       #[2,4,6,8]
  • 對文件的操作:例如只收集文件中以'p'開頭的行
    lines = [line.rstrip() for line in open('filename') if line[0] == 'p']
  • 對兩個集合進行排列組合:例如對'abc'與'lmn'進行排列組合
    str1 = 'abc'
    str2 = 'lmn'
    [x+y for x in str1 for y in str2]    #['al', 'am', 'an', 'bl', 'bm', 'bn', 'cl', 'cm', 'cn']

2、索引和分片

  • 對字符串的操作
    #索引操作
    s = 'spam'
    s[0]     # 's'
    s[-1]    # 'm'
    #分片操作
    s[1:3]    # 'pa'
    s[1:]      # 'pam'
    s[:-1]     # 'spa'
    s[:]        # 'spam'
    s[::2]     # 'sa'
    s[1::2]   # 'pm'
    s[::-1]    # 'maps'
    s[-1:0:-1] # 'map'
  • 對列表的操作
    #索引操作
    list1 = ['spam','SPAM','Spam']
    list1[0]     # 'spam'
    list1[-1]    # 'Spam'
    #分片操作
    list1[1:2]    # ['SPAM']
    list1[1:]      # ['SPAM', 'Spam']
    list1[:-1]     # ['spam', 'SPAM']
    list1[:]        # ['spam', 'SPAM', 'Spam']
    list1[::2]     # ['spam', 'Spam']
    list1[1::2]   # ['SPAM']
    list1[::-1]    # ['Spam', 'SPAM', 'spam']
    list1[-1:0:-1] # ['Spam', 'SPAM']

3、內置的eval函數可以將字符串轉換成對象

a='123'
type(a)          # 
type(eval(a))    # 

4、zip函數

  • 內置的zip函數使用for循環實現並行遍曆。在基本運算中,zip會取得一個或多個序列为参數,然後返回元組的列表,將這些序列中的並排的元素配成對。
    >>> l1 = [1,2,3,4]
    >>> l2 = [5,6,7,8]
    >>> zip(l1,l2)
    [(1, 5), (2, 6), (3, 7), (4, 8)]
  • 如果與 for 循環搭配,zip就會支持並行迭代
    >>> for (x,y) in zip(l1,l2):
    ...     print x, y, '--', x+y
    ...
    1 5 -- 6
    2 6 -- 8
    3 7 -- 10
    4 8 -- 12
  • 在運行時構造字典
    >>> keys = ['a', 'b', 'A', 'B']
    >>> values = [96, 97, 65, 66]
    >>> d = dict(zip(keys, values))
    >>> d
    {'a': 96, 'A': 65, 'B': 66, 'b': 97}

5、工廠函數 工廠函數有時也叫閉合(closure),一個能夠記住嵌套作用域變量值的函數,盡管那個作用域或許已經不存在了。 盡管類是最适合用作記憶狀態的,因为它們通過屬性賦值這個過程變得很明了,像這样的函數也提供了一種替代的解决方法。

>>> def maker(n):
    ...   def action(x):
    ...     return x ** n
    ...   return action
    ...
>>> f=maker(2)
>>> type(f)

>>> f(3)
9
>>> f(4)
16

6、匿名函數:lambda 除了def語句之外,Python還提供了一種生成函數對象的表達式形式。由於它於LISP語言中的一個工具很相似,所以稱为lambda。就像def一样,這個表達式創建了一個之後能夠調用的函數,但是它返回了一個函數而不是將這個函數賦值给一個變量名。這也就是lambda有時被稱作匿名函數的原因了。

  1. lambda通常用來編寫跳轉表(jump table),也就是行为的列表或字典,能夠按照需要執行相應的動作
    • 行为列表示例:
      >>> L = [(lambda x: x **2),(lambda x: x**3),(lambda x: x**4)]
      >>> for f in L:
      ...   print f(2)
      ...
      4
      8
      16
    • 行为字典示例:
      >>> key = 'got'
      >>> {'already':(lambda: 2+2),'got':(lambda: 2*4),'one':(lambda: 2**6)}[key]()
      8
      這样一個字典也就變成了一個多路分支的工具了
  2. lambda 與 if/else三元表達式的結合
    >>> lower = lambda x,y: x if x < y else y
    >>> lower('a','b')
    'a'
    >>> lower('b','a')
    'a'
  3. 如果要在lambda函數中執行循環,能夠嵌入map調用或列表解析表達式
    • 嵌入map的示例
      >>> import sys
      >>> showall = lambda x: map(sys.stdout.write,x)
      >>> t = showall(['spam\n','toast\n','eggs\n'])
      spam
      toast
      eggs
      
      >>> L = [1,2,3,4]
      >>> map((lambda x: x+3),L)
      [4, 5, 6, 7]
    • 嵌入列表解析的示例
      >>> showall = lambda x: [sys.stdout.write(line) for line in x]
      >>> t = showall(('bright\n','side\n','of\n','life\n'))
      bright
      side
      of
      life
  4. 嵌套作用域和lambda
    def func():
        x = 4
        action = (lambda n: x ** n)
        return action
    
    f = func()
    print f(2)    #16, 4**2

7、生成器

  • 概念 不像一般的函數會生成值後退出,生成器函數在生成值後自動掛起並暫停它們的執行和狀態。正是因为這一點,無論是在從頭計算整個序列的值,或者手動保存和恢 复類中的狀態時,它們都常常作为一種使用的替代解决方案。生成器在被掛起時自動地保存狀態,它的本地變量將保存狀態信息,這些信息在函數恢复時將再度有效。
  • 生成器函數和一般函數的區別:最大的區別就是生成器yield一個值,而不是return一個值。yield語句會將函數掛起,並向它的調用者返回一個值,但是保存足夠的狀態信息为了讓其能夠在函數從它掛起的地方恢复。這能夠允許這些函數不斷地產生一系列的值,而不是一次計算所有的值,之後將值以類似列表之類的形式來返回。
  • 生成器函數在Python中與迭代器協議的概念聯系在一起 包含了yield語句的函數將會特地編譯为生成器。當調用是,它們返回了一個生成器對象,這個生成器對象支持迭代器對象接口。生成器函數也許有一個return語句,這個語句就是用來終止產生值的。
  • 示例:
    >>> def gensquares(n):
    ...   for i in range(n):
    ...     yield i ** 2
    ...
    >>> type(gensquares(5))
    
    >>> for i in gensquares(5):
    ...   print i,',',
    ...
    0 , 1 , 4 , 9 , 16 ,
  • 生成器表達式: 生成器表達式就像一般的列表解析一样,但是它們是括在圓括號中而不是方括號中的。生成器表達式返回一個生成器對象。
    >>> for x in (x ** 2 for x in range(4)):
    ...   print x,
    ...
    0 1 4 9>>> for x in (x ** 2 for x in range(4)):
    ...   print x,
    ...
    0 1 4 9
    注意:如果生成器表達式是在其他括號之內的話,就像在那些函數調用之中,生成器自身的括號就不是必須的了。盡管這样,在下面第二個sorted調用中,還是需要額外的括號。
    >>> sum(x ** 2 for x in range(4))
    14
    >>> sorted(x ** 2 for x in range(4))
    [0, 1, 4, 9]
    >>> sorted((x ** 2 for x in range(4)), reverse=True)
    [9, 4, 1, 0]
    >>> import math
    >>> map(math.sqrt, (x ** 2 for x in range(4)))
    [0.0, 1.0, 2.0, 3.0]
     

 

 1、math模塊

>>> import math
>>> math.pi
3.1415926535897931
>>> math.e
2.7182818284590451
>>> math.sin(2*math.pi/180)
0.034899496702500969

2、random模塊

>>> import random
>>> random.random()
0.40019449172525789
>>> random.random()
0.063811948555701825
>>> random.randint(1,10)     3
>>> random.randint(1,10)     2

>>> random.choice(['a', 'b', 'c'])   'a'
>>> random.choice(['a', 'b', 'c'])    ‘c'

3、decimal模塊

>>> print 0.1+0.1+0.1-0.3
5.55111512313e-17
>>> from decimal import Decimal
>>> Decimal('0.1')+Decimal('0.1')+Decimal('0.1')-Decimal('0.3')
Decimal("0.0")

4、re正則表達式 re模塊能夠處理正則表達式的操作

  • 生成正則表達式對象 compile(pattern, flags=0)構建一個正則表達式,返回該正則表達式對象
    >>> import re
    >>> ptn1 = re.compile('he')
  • 進行匹配
    • match() 確定正則表達式是否匹配字符串的開頭
    • search() 掃描字符串以查找匹配
    • findall() 找到所有正則表達式匹配的子字符串,並把它們作为一個列表返回
    • finditer() 找到所有正則表達式匹配的子字符串,並把它們以迭代器的形式返回
    match()和search()在沒有發現匹配時返回None。如果匹配成功,一個MatchObject實例被返回,其中包含的匹配信息有:哪開始哪結束,匹配的子字符串等等。
    • group() 返回通過正則表達式匹配到的字符串
    • start() 返回成功匹配開始位置
    • end()   返回成功匹配結束位置
    • span()  返回包含成功匹配開始和結束位置的元組
    >>> import re
    >>> p1 = re.compile('h')
    >>> str1 = 'hello world'
    >>> md = p1.match(str1)
    >>> print md
    <_sre.SRE_Match object at 0x7f28e95c3238>
    >>> md.group()
    'h'
    >>> md.start()
    0
    >>> md.end()
    1
    >>> md.span()
    (0, 1)
    >>> p2 = re.compile('llo')
    >>> md2 = p2.search(str1)
    >>> md2.group()
    'llo'
    >>> md2.span()
    (2, 5)
    >>> p3 = re.compile('\d+')
    >>> str2 = '12abc3de45'
    >>> print p3.findall(str2)
    ['12', '3', '45']
    >>> iterator = p3.finditer(str2)
    >>> iterator
    
    >>> for match in iterator:
    ...     print match.span()
    ...
    (0, 2)
    (5, 6)
    (8, 10)

5、用pickle存儲Python的原生對象(對象的序列化以及反序列化) pickle模塊是能夠讓我們直接在文件中存儲幾乎任何Python對象的高級工具,也並不要求我們把字符串轉換來轉換去。

# 向文件中存儲數據
>>> data = {'a':97, 'b':98, 'A':65, 'B':66}
>>> datafile = open('data.txt','w')
>>> import pickle
>>> pickle.dump(data,datafile)
>>> datafile.close()
# 讀取存儲的數據
>>> datafile = open('data.txt')
>>> data = pickle.load(datafile)
>>> data
{'a': 97, 'A': 65, 'B': 66, 'b': 98}

6、文件中打包二進制數據的存儲與解析 struct模塊能夠構造並解析打包的二進制數據。

# 存儲
>>> f = open('data.bin','wb')
>>> import struct
>>> bytes = struct.pack('>i4sh', 7, 'spam', 8)
>>> bytes
'\x00\x00\x00\x07spam\x00\x08'
>>> f.write(bytes)
>>> f.close()
# 讀取
>>> f = open('data.bin','rb')
>>> data = f.read()
>>> data
'\x00\x00\x00\x07spam\x00\x08'
>>> values = struct.unpack('>i4sh', data)
>>> values
(7, 'spam', 8)

7、進程模塊工具

  1. Python的標准庫中與進程和線程相關的模塊和函數 模塊名稱 說明
    os/sys 包含基本進程管理函數
    subprocess Python基本庫中多進程相關模塊
    signal Python基本庫中信號相關模塊
  2. 進程的操作示例
    • os/sys模塊 創建進程
      • system函數 格式:system(command) 說明:此函數在新進程中執行command字符串命令。如果返回值为0,表示命令執行成功,否則表示失敗。 示例:
        >>> import os
        >>> print os.system('ls')
      • exec 家族函數 exec家族中有8個類似的函數(execl, execle, execlp, execlpe, execv, execve, execvp, execvpe)。雖然用他們都可以創建進程,但是和system函數還是有些不同。system函數實際上是調用系統內置的命令行程序來執行系統命令,所以在命令結束之後會將控制權返回给Python進程。但是,所有的exec函數在執行命令之後,將會接管Python進程,而不會將控制權返回。換句話說,Python進程會在調用exec函數後終止。新生成的進程將會替換調用進程。這些函數都沒有返回值,如果發生錯誤,將會觸發OSError異常。 execl 函數 格式:execl(path, arg0, arg1, ...) 示例:
        >>> import os
        >>> os.execl('/usr/bin/kate')
      終止進程 當Python腳本遇到最外層的return語句而退出的時候,這個進程也就終止了。除此之外,還有兩種方法終止進程: sys.exit 和os.abort
      • sys.exit函數 exit函數是一種"溫和"的終止進程方式,在程序退出之前會執行一些清理操作,同時將返回值给調用進程(一般是操作系統)。使用此返回值,系統可以判斷程序是否是正常退出或者運行出了異常。 例子:
        import sys
        try:
        filename = sys.argv[1]
        print filename
        except:
        print "Usage:", sys.argv[0], "filename"
        sys.exit(1)
      • os.abort 函數 和exit函數不同的是,abort函數是一種"暴力"的退出方式,將會直接给進程發送終止信號(SIGABORT信號)。默認情況下,這將會終止進程,同時不會做相關的清理工作。需要注意的是,可以使用signal.signal()來为SIGABORT信號注冊不同的信號處理函數,從而改變其默認行为。
    • subprocess 模塊 subprocess模塊是作为進程管理的高級模塊在2.4版本被引入的。subprocess可以調用外部的系統命令創建新的子進程,同時連接到子進程的input/output/error管道上,並得到子進程的返回值。這個模塊可以用來替代一些舊模塊的方法,如os.system, os.spawn*, os.popen*,popen2.*, commands.*等。subprocess模塊中提供了一個類和兩個使用函數來管理進程,下面將分別進行介紹。
      • 使用Popen類管理進程 class Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0) 其中,args参數为要執行的外部程序。其值可以是字符串或者序列。除此之外,其他的類参數都是有默認值,可以根據需要進行修改。
        import subprocess
        pingP = subprocess.Popen(args='ping -c 4 www.sina.com', shell=True)
        pingP.wait()
        print pingP.pid
        print pingP.returncode
        注:在Linux下,當shell为"False"時,Popen將調用os.execvp執行對應的程序。而shell为"True"時,如果命令为字符串,Popen直接調用系統shell來執行指定的程序。如果命令为一個序列,則其第一項是定義命令字符串,其他項为命令的附加参數。
      • subprocess模塊還提供了兩個實用函數來直接調用外部系統命令:call()和check_all()。 call()會直接調用命令生成子進程,並且等待子進程結束,然後返回子進程的返回值。check_all()和call()函數的主要區別在於:如果返回值不为0,則觸發CallProcessError異常。返回值保存在這個異常對象的returncode屬性中。
        import subprocess
        retcode = subprocess.call(['ls','-l'])   #調用ls -l 命令

你可能感兴趣的:(python)