Python內建函式(一)

veelion發表於2019-01-15

Python直譯器內建了很多函式和型別,可以隨時隨地在程式設計中使用。其實,我們在前面的學習中已經接觸過好多內建函式。

內建函式

這裡把它們總結成下面的表格,方便我們學習它們的使用:

內建函式列表

說明:
上面這個表格包含的有“內建函式”和“內建型別”,其中的內建型別可以作為函式使用,把其它型別的物件轉變為該型別的物件。比如int是一個內建型別,int('123')就是把字串轉換成整數。兩者在使用上沒有什麼區別,官方文件中也是把內建型別當做內建函式介紹的。

透過ipython,我們可以檢視錶格中的是函式還是型別。比如:

In [14]: abs?
Signature: abs(x, /)
Docstring: Return the absolute value of the argument.
Type:      builtin_function_or_method

In [15]: int?
Init signature: int(self, /, *args, **kwargs)
Docstring:     
int(x=0) -> integer
int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments
are given.  If x is a number, return x.__int__().  For floating point
numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string,
bytes, or bytearray instance representing an integer literal in the
given base.  The literal can be preceded by '+' or '-' and be surrounded
by whitespace.  The base defaults to 10.  Valid bases are 0 and 2-36.
Base 0 means to interpret the base from the string as an integer literal.
>>> int('0b100', base=0)
4
Type:           type
Subclasses:     bool, IntEnum, IntFlag, _NamedIntConstant

在ipython裡面透過問號?來檢視其對應的說明,其中的Type就是它的型別,可以看到abs是一個內建函式builtin_function_or_method,而int是一個型別type

我們把這些內建函式(型別)分成幾類進行介紹。

數值型操作

abs(x)
求x的絕對值。x可以是整數或浮點數,如果是複數則返回它的模。

bin(x)
將一個整數轉變為一個字首為0b的二進位制字串。結果是一個合法的 Python 表示式。如果 x 不是 Python 的 int 物件,那它需要定義 index() 方法返回一個整數。比如:

In [26]: bin(5)
Out[26]: '0b101'

In [27]: bin(-5)
Out[27]: '-0b101'

x 不能是浮點數,否則會報錯。
還可以透過format()函式來進行轉換:

In [30]: format(5, '#b')
Out[30]: '0b101'

In [31]: format(5, 'b')
Out[31]: '101'

還可以用f-string格式化來轉換:

In [32]: f'{5:#b}'
Out[32]: '0b101'

In [33]: f'{5:b}'
Out[33]: '101'

chr(i)
返回 Unicode 碼位為整數 i 的字元的字串格式。例如,chr(97) 返回字串 ‘a’,chr(20013) 返回字串 ‘中’。這是 ord() 的逆函式。

實參的合法範圍是 0 到 1,114,111(16 進製表示是 0x10FFFF)。如果 i 超過這個範圍,會觸發 ValueError 異常。

divmod(a, b)
它將兩個(非複數)數字作為實參,並在執行整數除法時返回一對商和餘數。對於混合運算元型別,適用雙目算術運算子的規則。對於整數,結果和 (a // b, a % b) 一致。對於浮點數,結果是 (q, a % b) ,q 通常是 math.floor(a / b) 但可能會比 1 小。在任何情況下, q * b + a % b 和 a 基本相等;如果 a % b 非零,它的符號和 b 一樣,並且 0 <= abs(a % b) < abs(b) 。

format(value[, format_spec])
將 value 轉換為 format_spec 控制的“格式化”表示。

hex(x)
將整數轉換為以“0x”為字首的小寫十六進位制字串。如果 x 不是 Python int 物件,則必須定義返回整數的 index() 方法。

oct(x)
將一個整數轉變為一個字首為“0o”的八進位制字串。結果是一個合法的 Python 表示式。如果 x 不是 Python 的 int 物件,那它需要定義 index() 方法返回一個整數。

ord(c)
對錶示單個 Unicode 字元的字串,返回代表它 Unicode 碼點的整數。例如 ord(‘a’) 返回整數 97, ord(‘€’) (歐元符合)返回 8364 。這是 chr() 的逆函式。

pow(x, y[, z])
返回 x 的 y 次冪;如果 z 存在,則對 z 取餘(比直接 pow(x, y) % z 計算更高效)。兩個引數形式的 pow(x, y) 等價於冪運算子: x**y

round(number[, ndigits])
返回精確到小數點後ndigits精度的數。 如果省略ndigits或者為None,則返回其輸入的最接近的整數。

對於支援round()的內建型別,值被舍入離前一位更近的一端(四捨六入); 如果距離兩端相等(5)則保留到偶數一邊。(例如,round(0.5)和round(-0.5)均為0,round(1.5)為2)。 任何整數值對ndigits(正數,零或負數)有效。如果省略ndigits或None,則返回值為整數。 否則返回值與number的型別相同。

對於一般的Python物件number,將代理舍入為number.__round__

註釋: round()對於浮點數的行為可能令人驚訝,比如,round(2.675, 2)得出2.67,而不是期望的2.68。這不是bug,這是因為大多數十進位制小數不能準確表示為二進位制的浮點數。

sum(iterable[, start])

start開始由左到右累加可迭代的元素並返回總數。start預設為0. iterable的項通常是數字,起始值不允許是字串。

對於某些用例,sum()有很好的替代方法。 連線字串序列的首選快速方法是呼叫''.join(sequence)。 要以擴充套件精度累加浮點值,就用math.fsum()。要拼接一系列可迭代物件就考慮使用itertools.chain()

可迭代操作

all(iterable), any(iterable)
這兩個函式,我們在前面學習list、dict等資料結構時已經多次學習。
all(): 如果iterable的所有元素都為真(或iterable為空)返回True;等價於:

def all(iterable):
    for item in iterable:
        if not item:
            return False
    return True

any():如果iterable的任一個元素為真則返回True。如果iterable為空,則返回False。等價於:

def any(iterable):
    for item in iterable:
        if item:
        return True
    return False

enumerate(iterable, start=0)
返回一個列舉物件。iterable 必須是一個序列,或 iterator,或其他支援迭代的物件。 enumerate() 返回的迭代器的 next() 方法返回一個元組,裡面包含一個計數值(從 start 開始,預設為 0)和透過迭代 iterable 獲得的值。

In [4]: ll = ['a', 'b', 'c', 'd']

In [5]: list(enumerate(ll))
Out[5]: [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]

In [6]: list(enumerate(ll, start=1))
Out[6]: [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')]

等價於:

def enumerate(sequence, start=0):
    n = start
    for elem in sequence:
        yield n, elem
        n += 1

filter(function, iterable)
用 iterable 中函式 function 返回真的那些元素,構建一個新的迭代器。iterable 可以是一個序列,一個支援迭代的容器,或一個迭代器。如果 function 是 None ,則會假設它是一個身份函式,即 iterable 中所有返回假的元素會被移除。

請注意, filter(function, iterable) 相當於一個生成器表示式,當 function 不是 None 的時候為 (item for item in iterable if function(item));function 是 None 的時候為 (item for item in iterable if item) 。
只有 function 返回 false 時才選取 iterable 中元素的補充函式。

map(function, iterable, …)
產生一個將 function 應用於迭代器中所有元素並返回結果的迭代器。如果傳遞了額外的 iterable 實參,function 必須接受相同個數的實參,並使用所有迭代器中並行獲取的元素。當有多個迭代器時,最短的迭代器耗盡則整個迭代結束。如果函式的輸入已經是元組實參,請參閱 itertools.starmap()。

zip(*iterables)
建立一個聚合來自每個可迭代的元素的迭代器。

返回元組的迭代器,其中第i個元組包含來自每個引數序列或迭代的第i個元素。當最短輸入可迭代用盡時,迭代器停止。使用單個iterable引數,它返回一個1元組的迭代器。沒有引數,它返回一個空迭代器。相當於:

def zip(*iterables):
    # zip('ABCD', 'xy') --> Ax By
    sentinel = object()
    iterators = [iter(it) for it in iterables]
    while iterators:
        result = []
        for it in iterators:
            elem = next(it, sentinel)
            if elem is sentinel:
                return
            result.append(elem)
        yield tuple(result)

保證了迭代的從左到右的評估順序。 這使得使用zip(*[iter(s)]*n)將資料系列聚類成n長度組的習慣成為可能。這會重複相同的迭代器n次,以便每個輸出元組具有n次呼叫迭代器的結果。這具有將輸入分成n長度塊的效果。

當你不關心較長迭代的尾隨,不匹配的值時,zip()只應與不等長度輸入一起使用。如果這些值很重要,請改用itertools.zip_longest()

zip()與*運算子一起用於解壓縮列表:

In [80]: a = [1, 2, 3]

In [81]: b = ['a', 'b', 'c']

In [82]: zipped = zip(a, b)

In [83]: list(zipped)
Out[83]: [(1, 'a'), (2, 'b'), (3, 'c')]

In [84]: a2, b2 = zip(*zip(a, b))

In [85]: a == list(a2) and b == list(b2)
Out[86]: True

max(iterable, *[, key, default])
max(arg1, arg2, *args[, key])
返回可迭代物件中最大的元素,或者返回兩個及以上實參中最大的。

如果只提供了一個位置引數,它必須是非空 iterable,返回可迭代物件中最大的元素;如果提供了兩個及以上的位置引數,則返回最大的位置引數。

有兩個可選只能用關鍵字的實參。key 實參指定排序函式用的引數,如傳給 list.sort() 的。default 實參是當可迭代物件為空時返回的值。如果可迭代物件為空,並且沒有給 default ,則會觸發 ValueError。

如果有多個最大元素,則此函式將返回第一個找到的。這和其他穩定排序工具如 sorted(iterable, key=keyfunc, reverse=True)[0] 和 heapq.nlargest(1, iterable, key=keyfunc) 保持一致。

min(iterable, *[, key, default])
min(arg1, arg2, *args[, key])
返回可迭代物件中最小的元素,或者返回兩個及以上實參中最小的。

如果只提供了一個位置引數,它必須是 iterable,返回可迭代物件中最小的元素;如果提供了兩個及以上的位置引數,則返回最小的位置引數。

有兩個可選只能用關鍵字的實參。key 實參指定排序函式用的引數,如傳給 list.sort() 的。default 實參是當可迭代物件為空時返回的值。如果可迭代物件為空,並且沒有給 default ,則會觸發 ValueError。

如果有多個最小元素,則此函式將返回第一個找到的。這和其他穩定排序工具如 sorted(iterable, key=keyfunc)[0] 和 heapq.nsmallest(1, iterable, key=keyfunc) 保持一致。

reversed(seq)
返回反向迭代器。seq必須是一個具有reversed()方法的物件,或者支援序列協議(len()方法和getitem()方法,整數引數從0開始)。

sorted(iterable, *, key=None, reverse=False)

從iterable中的項返回一個新的排序列表。

有兩個可選引數,必須指定為關鍵字引數。

key指定一個引數的函式,該函式用於從iterable中的每個元素中提取比較鍵(例如,key = str.lower)。預設值為None(直接比較元素)。

reverse是一個布林值。 如果設定為True,則列表元素將按照每個比較相反的方式進行排序。

使用functools.cmp_to_key()將舊式cmp函式轉換為鍵函式。

內建的sorted()函式保證穩定。 如果排序保證不改變比較相等的元素的相對順序,則排序是穩定的 – 這有助於多次傳遞排序(例如,按部門排序,然後按工資等級排序)。

iter(object[, sentinel])
返回一個 iterator 物件。根據是否存在第二個實參,第一個實參的解釋是非常不同的。如果沒有第二個實參,object 必須是支援迭代協議(有 iter() 方法)的集合物件,或必須支援序列協議(有 getitem() 方法,且數字引數從 0 開始)。如果它不支援這些協議,會觸發 TypeError。如果有第二個實參 sentinel,那麼 object 必須是可呼叫的物件。這種情況下生成的迭代器,每次迭代呼叫它的 next() 方法時都會不帶實參地呼叫 object;如果返回的結果是 sentinel 則觸發 StopIteration,否則返回撥用結果。

next(iterator[, default])
透過呼叫 iterator 的 next() 方法獲取下一個元素。如果迭代器耗盡,則返回給定的 default,如果沒有預設值則觸發 StopIteration。

內建型別

class bool([x])
說明:在文件中,函式的引數用方括號[]括起來表示這個引數可有可無(在引數列表中)。
內建型別,返回一個布林值:True或者Falsex使用標註的真值測試過程來轉換,關於真值測試的知識可以再回顧一下前面我們關於布林值的章節。
bool類是int的子類,這個bool類很特別,它不能被繼承,且只有TrueFalse兩個例項。

class bytearray([source[, encoding[, errors]]])
返回一個新的 bytes 陣列。 bytearray 類是一個可變序列,包含範圍為 0 <= x < 256 的整數。它有可變序列大部分常見的方法,同時有 bytes 型別的大部分方法。
可選形參 source 可以用不同的方式來初始化陣列:

如果是一個 string,您必須提供 encoding 引數(errors 引數仍是可選的);bytearray() 會使用 str.encode() 方法來將 string 轉變成 bytes。

  • 如果是一個 integer,會初始化大小為該數字的陣列,並使用 null 位元組填充。
  • 如果是一個符合 buffer 介面的物件,該物件的只讀 buffer 會用來初始化位元組陣列。
  • 如果是一個 iterable 可迭代物件,它的元素的範圍必須是 0 <= x < 256 的整數,它會被用作陣列的初始內容。

如果沒有實參,則建立大小為 0 的陣列。

class bytes([source[, encoding[, errors]]])
返回一個新的“bytes”物件, 是一個不可變序列,包含範圍為 0 <= x < 256 的整數。bytes 是 bytearray 的不可變版本 – 它有其中不改變序列的方法和相同的索引、切片操作。

因此,建構函式的實參和 bytearray() 相同。

class complex([real[, imag]])
返回值為 real + imag*1j 的複數,或將字串或數字轉換為複數。如果第一個形參是字串,則它被解釋為一個複數,並且函式呼叫時必須沒有第二個形參。第二個形參不能是字串。每個實參都可以是任意的數值型別(包括複數)。如果省略了 imag,則預設值為零,建構函式會像 int 和 float 一樣進行數值轉換。如果兩個實參都省略,則返回 0j。

註解 當從字串轉換時,字串在 + 或 – 的周圍必須不能有空格。例如 complex(‘1+2j’) 是合法的,但 complex(‘1 + 2j’) 會觸發 ValueError 異常。
在 3.6 版更改: 您可以使用下劃線將程式碼文字中的數字進行分組。

class float([x])
返回從數字或字串 x 生成的浮點數。

如果實參是字串,則它必須是包含十進位制數字的字串,字串前面可以有符號,之前也可以有空格。可選的符號有 ‘+’ 和 ‘-‘ ; ‘+’ 對建立的值沒有影響。實參也可以是 NaN(非數字)、正負無窮大的字串。

class int([x])
class int(x, base=10)
返回一個使用數字或字串 x 生成的整數物件,或者沒有實參的時候返回 0 。如果 x 定義了 int(),int(x) 返回 x.int() 。如果 x 定義了 trunc(),它返回 x.trunc() 。對於浮點數,它向零舍入。

如果 x 不是數字,或者有 base 引數,x 必須是字串、bytes、表示進製為 base 的 整數文字 的 bytearray 例項。該文字前可以有 + 或 – (中間不能有空格),前後可以有空格。一個進製為 n 的數字包含 0 到 n-1 的數,其中 a 到 z (或 A 到 Z )表示 10 到 35。預設的 base 為 10 ,允許的進位制有 0、2-36。2、8、16 進位制的數字可以在程式碼中用 0b/0B 、 0o/0O 、 0x/0X 字首來表示。進製為 0 將安照程式碼的字面量來精確解釋,最後的結果會是 2、8、10、16 進位制中的一個。所以 int(‘010’, 0) 是非法的,但 int(‘010’) 和 int(‘010’, 8) 是合法的。

class str(object=”)
class str(object=b”, encoding=’utf-8′, errors=’strict’)

返回一個str型別的物件。str是內建字串類

class list([iterable])
除了是函式,list 也是可變序列型別,詳情請參閱 列表 和 Sequence Types — list, tuple, range。

tuple([iterable])
元組是內建的不可變序列型別。tuple()生成一個元組物件,可選引數iterable的元素將被加入到新元組。

class dict(**kwarg)
class dict(mapping, **kwarg)
class dict(iterable, **kwarg)
建立一個新的字典。dict 物件是一個字典類
其他容器型別,請參見內建的 list、set 和 tuple 類,以及 collections 模組。

class set([iterable])
返回一個set物件。可選引數iterable的元素將被加入新set物件裡面。

class frozenset([iterable])
返回一個新的 frozenset 物件,它包含可選引數 iterable 中的元素。 frozenset 是一個內建的類。

class object
返回一個沒有特徵的新物件。object 是所有類的基類。它具有所有 Python 類例項的通用方法。這個函式不接受任何實參。

註解 由於 object 沒有 dict,因此無法將任意屬性賦給 object 的例項。

class range(stop)
class range(start, stop[, step])
range其實是個不可變數字序列型別而不是一個函式,通常用於在for迴圈中迴圈特定次數。
傳給range的實參必須是整數(或是內建型別int,或是實現了index這個特殊方法的物件)。如果step引數省略了,則它預設為1.如果start省略了則預設為0。如果step為0,則報錯:ValueError

如果step為整數,range 的內容決定於公式:r[i] = start + step*i,其中i >= 0, r[i] < stop

如果step是負數,range 的內容仍決定於公式:r[i] = start + step*i,其中i >= 0, r[i] > stop

如果r[0]不滿足值約束,則range物件將為空。 range確實支援負索引,但這些索引被解釋為從正索引確定的序列末尾開始的索引。

range被允許包含絕對值大於sys.maxsize的值,但是某些特性(如len())可能會報錯:OverflowError
參看下面range的例子:

In [32]: list(range(9))
Out[32]: [0, 1, 2, 3, 4, 5, 6, 7, 8]

In [33]: list(range(3,9))
Out[33]: [3, 4, 5, 6, 7, 8]

In [34]: list(range(0, 20, 3))
Out[34]: [0, 3, 6, 9, 12, 15, 18]

In [35]: list(range(0, -10, -1))
Out[35]: [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]

In [36]: list(range(0))
Out[36]: []

In [37]: list(range(10, 0))
Out[37]: []

range型別比通常的list或tuple的優點是,range對線下總是佔用相同(小的)數量的記憶體,不管它表示的範圍有多大。因為它只儲存startstopstep的值,在需要的時候才計算單獨的元素或子範圍。

range物件實現了類似list或tuple序列的特性,比如包含測試,元素索引查詢,切片和對負索引的支援。參見下面的例子:

In [43]: r = range(0, 10, 2)

In [44]: r
Out[44]: range(0, 10, 2)

In [45]: 5 in r
Out[45]: False

In [46]: 6 in r
Out[46]: True

In [47]: r.index(8)
Out[47]: 4

In [48]: r[3]
Out[48]: 6

In [49]: r[:3]
Out[49]: range(0, 6, 2)

In [50]: r[-1]
Out[50]: 8

透過==!=測試兩個range物件的相等性是把它們當做序列進行比較。也就是說,如果兩個range物件表示相同的值的序列就認為它們實時相等的。

注意:兩個range物件相等但可能含有不同的startstopstep屬性,比如range(0) == range(2, 1, 1)或者range(0, 3, 2) == range(0, 4, 2)

class slice(stop)
class slice(start, stop[, step])

返回一個切片物件,表示由range(start,stop,step)指定的索引集。start和step引數預設為None。Slice物件具有隻讀資料屬性start,stop和step,它們只返回引數值(或它們的預設值)。他們沒有其他明確的功能;但是它們被Numerical Python和其他第三方擴充套件使用。使用擴充套件索引語法時也會生成切片物件。例如:a[start:stop:step]或a[start:stop,i]。

class type(object)
class type(name, bases, dict)

傳入一個引數object,則返回該物件的型別。返回值是一個type物件,通常和object.__class__返回的一樣。
建議使用isinstance()內建函式來測試物件的型別,因為它需要考慮子類。
使用三個引數,返回一個新型別物件。 這實際上是類語句的動態形式。 名稱字串是類名,併成為name屬性; 基元元組列出基類併成為bases屬性; 並且dict字典是包含類主體定義的名稱空間,並被複制到標準字典以成為dict屬性。 例如,以下兩個語句建立相同的型別物件:

In [77]: class A: 
    ...:     a = 1 
    ...:

In [78]: A = type('A', (object,), dict(a=1))

猿人學banner宣傳圖

我的公眾號:猿人學 Python 上會分享更多心得體會,敬請關注。

***版權申明:若沒有特殊說明,文章皆是猿人學 yuanrenxue.com 原創,沒有猿人學授權,請勿以任何形式轉載。***

相關文章