Python 強制類型轉換


學習過程中遇到了強轉問題,這里整理一下。

 

前言

本篇主要介紹Python的強制類型轉換。

軟件環境

  • 系統
    • UbuntuKylin 14.04
  • 軟件
    • Python 2.7.3
    • IPython 4.0.0

Python數據類型的顯式轉換

數據類型的顯示轉換,也稱為數據類型的強制類型轉換,是通過Python的內建函數來實現的類型轉換。

顯式轉換的多種類型

int(x [,base]) ⇒ 將x轉換為一個十進制的整數
long(x [,base]) ⇒ 將x轉換為一個十進制的長整數
float(x) ⇒ 將x轉換為一個浮點數
str(object) ⇒ 轉換為字符串
repr(object) ⇒ 轉換為表達式字符串
eval(str) ⇒ 用來計算在字符串中的有效Python表達式,並返回一個對象
tuple(seq) ⇒ 將序列seq轉換為一個元組
list(seq) ⇒ 將序列seq轉換為一個列表
chr(x ) ⇒ 將一個整數轉換為一個字符
unichr(x ) ⇒ 將一個整數轉換為Unicode字符
ord(x ) ⇒ 將一個字符轉換為它的整數值
hex(x ) ⇒ 將一個整數轉換為一個十六進制字符串
oct(x ) ⇒ 將一個整數轉換為一個八進制字符串

下面詳細介紹一些常用的類型轉換。

Non-String轉換為String

str()函數

str(object=”) -> string
Return a nice string representation of the object.
If the argument is a string, the return value is the same object.
str()是最常用的轉換為String的內建函數,可以接受任意對象,並將其轉換為String類型。若object為String類型,則返回一個同類型的對象。
將List對象轉換為String

In [13]: li Out[13]: ['My', 'Name', 'Is', 'Jmilk'] In [14]: strLi = str(li) In [15]: print strLi[0] [

將Tuple對象轉換為String

In [19]: tup = ('my','name','is','jmilk') In [20]: str(tup) Out[20]: "('my', 'name', 'is', 'jmilk')" In [22]: str(tup)[3] Out[22]: 'y'

將Dictionary對象轉換為String

In [23]: dic = {'name':'Jmilk','age':23} In [24]: str(dic) Out[24]: "{'age': 23, 'name': 'Jmilk'}" In [25]: str(dic)[3] Out[25]: 'g'

上面3個例子可以發現,在轉換為String后無論是原來的特殊符號還是空格符都會成為String的元素之一。

repr()

repr(object) -> string
Return the canonical string representation of the object.
For most object types, eval(repr(object)) == object.
repr()函數的使用方法於str()函數類似,都是傳入一個任意對象,再返回一個String類型對象,但兩者卻有着本質的區別。

str()和repr()的區別

主要的區別就在repr()支持eval(repr(object)) == object。str()函數的目標是一般用戶的可讀性,返回一個更適合人閱讀的nice string。而repr()則返回一個更適合python解析器閱讀的canonical strng,同時會返回Python解析器能夠識別的數據細節,但這些細節對一般用戶來說是多余的。而且repr()轉換后的String對象可以通過求值運算eval()來還原到轉換之前的對象,相比之下str()通常不需要eval()去處理。

In [61]: name = ('My name is Jmilk\n') In [62]: print str(name) My name is Jmilk In [63]: print repr(name) 'My name is Jmilk\n'

上面例子可以看出str()打印出來的字符串會更符合人的閱讀習慣。

eval()

eval()函數,能夠結合repr()函數將一個經過轉換為Strng類型后的對象還原為轉換之前的對象類型。同時eval()也被稱為求值運算,可以將字符串str當成有效的表達式來求值並返回計算結果。

In [64]: name = ('My name is Jmilk\n') In [65]: name1 = str(name) In [66]: name1 Out[66]: 'My name is Jmilk\n' In [67]: name2 = repr(name) In [68]: name2 Out[68]: "'My name is Jmilk\\n'" In [69]: eval(name1) File "<string>", line 1 My name is Jmilk ^ SyntaxError: invalid syntax In [70]: eval(name2) Out[70]: 'My name is Jmilk\n'

eval(str(Object))可能會報錯,無法還原為原來的對象型。而eval(repr(object))卻可以還原,下面例子:

In [81]: name = ('My','name','is','Jmilk\n') In [82]: repr(name) Out[82]: "('My', 'name', 'is', 'Jmilk\\n')" In [83]: eval(repr(name)) Out[83]: ('My', 'name', 'is', 'Jmilk\n') In [84]: type(eval(repr(name))) Out[84]: tuple

總結:這是因為str()函數主要是為了讓人能夠更好的閱讀其內容,而rper()除了轉換為String類型外,還能夠被Python解析器識別其數據細節,從而repr()轉換后的字符串能夠被當作有效表達式來處理。
注意:eval()函數最主要的功能是能夠將字符串中有效的表達式進行計算並返回一個對象。如下:

In [141]: sum = '100+10' In [142]: eval(sum) Out[142]: 110

Non-int轉換為int

Int型的最大值僅與系統位數有關,32位:maxInt == 2**(32-1)-1 ; 64位:maxInt == 2**(64-1)-1。可以通過sys.maxint
來查看:

In [42]: sys.maxint Out[42]: 9223372036854775807 In [43]: 2**63-1 Out[43]: 9223372036854775807L

在Python2.4x版本之后為Int增加了Long的隱式轉換來防止數據范圍溢出。
int(x[, base=10]) -> int or long
base:指定進制
x:通常為一個String
base指定了x的進制

Long轉換為Int,使用自定義函數

當一個Long > sys.maxint(2**63-1)時,Long類型對象是無法轉換為Int的。
Example:

In [79]: int(2**63) Out[79]: 9223372036854775808L #仍為Long類型

下面使用一個自建的函數來實現當Long > sys.maxint時的Long到Int的強制類型轉換。需要實現兩個方面,一個是轉換數值(不能超過maxint),另一個是轉換類型為int。
轉換數值

In [130]: %pycat longToInt.py import sys def longToInt(value): if value > sys.maxint: return (value & sys.maxint) else: return value if __name__ == '__main__': number = 2**63 result = longToInt(number) print 'number - sys.maxint = %s - %s = %s' % (number,sys.maxint,result) print 'result is %s,result type is %s;number type is %s' % (result,type(result),type(number)) In [131]: run longToInt.py number - sys.maxint = 9223372036854775808 - 9223372036854775807 = 1 result is 0,result type is <type 'long'>;number type is <type 'long'>

上例:當number-sys.maxint=1時,將Long型number的數值轉化為0輸出。即當一個int類型的數值超過sys.maxint時,再將多余於的數值環回計數。以此類推,當number-sys.maxint=101時,Long型的number的環回計數為100。
需要注意的是:盡管數值是大於maxint,但是其數據類型仍然為long,可以使用int()函數將環回的數值轉化為Int型,且只能在轉換數值后才能成功額轉換類型。
轉換類型

In [136]: %pycat longToInt.py import sys def longToInt(value): if value > sys.maxint: return (value & sys.maxint) else: return value if __name__ == '__main__': number = 2**63+100 result = longToInt(number) print 'number - sys.maxint = %s - %s = %s' % (number,sys.maxint,result+1) print 'result is %s,result type is %s;number type is %s' % (result,type(int(result)),type(number)) In [137]: run longToInt.py number - sys.maxint = 9223372036854775908 - 9223372036854775807 = 101 result is 100,result type is <type 'int'>;number type is <type 'long'>

Float轉換為Int

浮點型轉為整型會進行向下取整。

In [130]: int(10.9) Out[130]: 10

String轉換為Int

In [131]: int('0xa',16) Out[131]: 10 In [132]: int('1010',2) Out[132]: 10

參數16表示’0xa’為16進制數,int()轉換以后獲得10進制數,若不指明’0xa’的進制,則會報錯。

In [133]: int('0xa') ValueError: invalid literal for int() with base 10: '0xa'

Non-long轉化為long類型

long(x=0) -> long
long(x, base=10) -> long
生成一個long對象

In [24]: long(10) Out[24]: 10L

也可以簡單的實現:

In [138]: num = 10L In [139]: type(num) Out[139]: long

Int轉化為Long

int型轉換為long型不需要強制類型轉換,這就是相對的隱式類型轉換,系統會在后台完成。在后面的博文中再作介紹。

Float轉換為Long

向下取整

In [27]: long(10.9) Out[27]: 10L

String轉換為Long

In [33]: long('0xa',16) Out[33]: 10L In [34]: long('1010',2) Out[34]: 10L

可以看出,Int與Long類型的數據非常類似,唯一的區別在於,Long類型的數據范圍更加大。(Int)

Non-float轉換為float

float(x) -> floating point number
Convert a string or number to a floating point number, if possible.
可以接收Int和String類型參數,float()函數在連接數據庫操作會被經常使用。當參數為String時,只能出現數字和一個點額任意組合,若出現多個點號,則會出現異常。

In [194]: float(10) Out[194]: 10.0 In [195]: float('100') Out[195]: 100.0 In [199]: float('.1111') Out[199]: 0.1111 In [204]: float('.98.') --------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-204-70a1a06c7ce5> in <module>() ----> 1 float('.98.') ValueError: invalid literal for float(): .98.

Sequence轉換為List

list(iterable) -> new list initialized from iterable’s items
使用迭代器中的元素生成一個新的列表

String轉換為List

將字符串中的每一個字母作為列表中的一個元素,空格也算是一個元素

In [137]: name = 'My name is Jmilk' In [138]: list(name) Out[138]: ['M', 'y', ' ', 'n', 'a', 'm', 'e', ' ', 'i', 's', ' ', 'J', 'm', 'i', 'l', 'k']

Tuple轉換為List

Tuple轉換為List與String其實大同小異:

In [1]: tup = ('My','name','is','Jmilk') In [2]: list(tup) Out[2]: ['My', 'name', 'is', 'Jmilk']

將Tuple對象中的每一個元素轉換為List中的每個元素。

Sequence轉換為Tuple

tuple(iterable) -> tuple initialized from iterable’s items
利用迭代器中的元素生成新的元組

String轉換為Tuple

In [5]: str = 'My name is Jmilk!' In [6]: tuple(str) Out[6]: ('M', 'y', ' ', 'n', 'a', 'm', 'e', ' ', 'i', 's', ' ', 'J', 'm', 'i', 'l', 'k', '!')

類似String轉換為List,空格任然算一個元素

List轉換為Tuple

In [9]: li Out[9]: ['My', 'name', 'is', 'Jmilk'] In [10]: tuple(li) Out[10]: ('My', 'name', 'is', 'Jmilk')

將List和Tuple復合數據類型轉換為Dictionary

格式:dict([(key1,value1),..])

In [144]: li = ['name','age','city'] In [145]: tup = ('jmilk',23,'BJ') In [146]: zip(li,tup) Out[146]: [('name', 'jmilk'), ('age', 23), ('city', 'BJ')] In [148]: dict(zip(li,tup)) Out[148]: {'age': 23, 'city': 'BJ', 'name': 'jmilk'}

Dictionary轉換為List

相對的,Dictionary的鍵值對也能夠轉換為List和Tuple的復合數據類型。
D.items() -> list of D’s (key, value) pairs, as 2-tuples

In [159]: dic Out[159]: {'age': 23, 'city': 'BJ', 'name': 'jmilk'} In [160]: dic.items() Out[160]: [('city', 'BJ'), ('age', 23), ('name', 'jmilk')]

Int轉換為字符char

chr(i) -> character
Return a string of one character with ordinal i; 0 <= i < 256.
以整數所對應的ASCII碼來轉換為Char,i屬於[0,256)。

In [174]: chr(65) Out[174]: 'A' In [175]: chr(97) Out[175]: 'a'

最后

強制數據類型轉換在編程過程中國非常常見,且在對內存、時間等運行環境要求嚴格的程序中尤為重要。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM