天天看點

Python 資料類型和控制結構

     Python是一門腳本語言,我也久聞大名,但正真系統的接觸學習是在去年(2013)年底到今年(2014)年初的時候。不得不說的是Python的官方文檔相當齊全,如果你是在Windows上學習Python,安裝包自帶的“Python Manuals”就是一份很好的學習資料(基本上不用去找其他資料了);尤其是其中的Tutorial,非常适合初學者。本文一方面總結了python語言的核心——資料類型和控制結構;另一方面,通過與其他語言的對比表達了我對Python的一些拙見。

資料類型

Python簡潔的背後是因為有着強大的類型系統的支援。Python世界的基本資料類型有{int, long, float, complex, str, list, set, tuple, dict},下面通過Python解釋器在互動模式下的輸入輸出執行個體進行示範(其中有前導符>>>或...的是輸入):

tips: Python世界裡,可以用type(x)來輸出x的類型.

int, long, float, str, complex

>>> type(123)
<type 'int'>
>>> type(-234)
<type 'int'>
>>> type(123456123456)
<type 'long'>
>>> type(-123456123456)
<type 'long'>
>>> type(123.456)
<type 'float'>
>>> type('abc')
<type 'str'>
>>> type("hello, world")
<type 'str'>      

從最後兩次輸入可以看到Python的字元串可以用單引号也可以用雙引号。另外,大家可能會疑惑的是到底多大是int和多大是long呢?下面我們來一探究竟:

>>> type(123456)
<type 'int'>
>>> type(123456789)
<type 'int'>
>>> type(1234567890)
<type 'int'>
>>> type(12345678901)
<type 'long'>      

可以看到1234567890還是int,12345678901就是long了,說明int是有範圍的。記得C/C++的int長度(4B)的同學都知道,C/C++裡int的取值範圍是:[-2^31, 2^31-1]也就是[-2147483648, 2147483647]。據此,我們可以看看Python的int範圍:

>>> type(2147483647)
<type 'int'>
>>> type(2147483648)
<type 'long'>
>>> type(-2147483648)
<type 'int'>
>>> type(-2147483649)
<type 'long'>      

這次試驗說明,Python的int範圍和C/C++一樣。(事實上和long一樣,這裡隻是因為運作的是32位的python解釋器,如果是64位python解釋器,int是8位元組)

那麼,如果我想指定一個比較小的long怎麼辦呢?可以通過加L(或小寫l)字尾:

>>> type(1L)
<type 'long'>
>>> type(2l)
<type 'long'>      

另外,Python的浮點數是沒有double的:

>>> type(123.456)
<type 'float'>
>>> type(123456123456.123456123456123456123456)
<type 'float'>      

complex(複數)

複數類型在很多語言中是沒有的,Python通過整數加J(或小寫j)字尾表示複數:

>>> type(3+4j)
<type 'complex'>
>>> type(3+4J)
<type 'complex'>
>>> type(4j)
<type 'complex'>
>>> type(j)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'j' is not defined
>>> type(1j)
<type 'complex'>      

但是1j不允許直接寫成j,j會被當做name查找,如果沒找到就會報錯。

tuple, list, set, dict

tuple, list, set, dict分别是元組、清單、集合、字典(有的語言叫映射map)。這些類型才是Python類型系統的過人之處,在多數編譯型語言(C、C++、Java、C#等)中,這些類型都要通過庫來提供(如C++、Java、C#),有的或許庫也沒有提供(如C)。

>>> type([1, 2, 3])
<type 'list'>
>>> type({2, 3, 4})
<type 'set'>
>>> type((3, 4, 5))
<type 'tuple'>
>>> type({'key1': 'value1', 'key2': 'value2'})
<type 'dict'>      

可以看到(), [], {}和它括起來的一系列元素,分别是表示:元組、清單、集合。而dict則是{key1: value1, [key2: value2, ...]}的形式。

上面列出的各種集合的元素類型一緻,這在編譯型語言裡通常是必須的,但在Python裡不必:

>>> (1, 'two', 3.0)
(1, 'two', 3.0)
>>> [(1, 'two', 3.0), '4', 5]
[(1, 'two', 3.0), '4', 5]
>>> {1, 2L, 3.0, 4j}
set([1, 2L, 3.0, 4j])
>>> {1: 'one', 'one': 1}
{1: 'one', 'one': 1}      

控制結構

結構化程式設計方法提出之時,就有前輩證明了任何算法都可以使用:順序、選擇、循環三種結構表達。下面将展示Python的基本文法,以及選擇和循環。

順序結構

順序結構本身沒什麼好說的,這裡介紹一下Python的其他特性。

語句

Python的語句以換行符結尾(不像C家族的分号結尾):

>>> print "hello, world"
hello, world      

并且Python程式沒有所謂的“入口”,這和多數腳本語言類似。

弱類型

Python是弱類型的,也就是變量的類型不是一成不變的。這也和很多腳本語言類似。

>>> a = 123
>>> b = "asdf"
>>> c = [3, 4, 5]
>>> a
123
>>> b
'asdf'
>>> c
[3, 4, 5]
>>> a = b
>>> b
'asdf'
      

這段互動中有兩點與C語言(C++等)不同:

  1. 使用變量前不用向提前聲明變量的類型
  2. 一個變量初始化為一個類型後還能給他賦其他類型的值

提示:在Python解釋器的互動模式下直接輸入變量名也能顯示變量的值

“變量”一詞在Python裡應該叫“名字”(或者符号)更确切,在Python中你可以給一個符号賦予任何類型的值。稍後你将會看到可以給原本指派為int的對象指派為一個函數,一個類。

函數

Python的函數定義以def開始,如果有傳回值需要用return傳遞傳回值。

比如如下代碼定義了一個名為sayHello的函數,并用'Jack'為參數進行了一次調用:

def sayHello(name):
	print 'Hello, ' + name + '!'
	
sayHello('Jack')      

這段代碼的運作結果為:Hello, Jack!

(可将這段代碼儲存為sayHello.py,然後在對應目錄運作python sayHello.py)

Python的類定義以class開始,屬性可以在class下方聲明也可以在__init__方法裡通過self.xxx隐式聲明。

先來一段最簡單的關于類的代碼:

class Man:	
	def __init__(self, name):
		self.name = name
	
	def hello(self):
		print 'Hello, ' + self.name + '!'

m = Man('Jack')
m.hello()      

這段代碼也會輸出:Hello, Jack!

tips: Python方法的第一個參數必須是名為self的參數,用于操作對象的成員。__init__類似其他語言的”構造方法“。

類的更多特性和OOP有關,以後有時間再單獨發一篇博文展示。

順便看看函數、類以及類的執行個體在Python解釋器眼中都是什麼:

>>> type(sayHello)
<type 'function'>
>>> type(Man)
<type 'classobj'>
>>> type(m)
<type 'instance'>
>>> type(m.hello)
<type 'instancemethod'>
>>> type(Man.hello)
<type 'instancemethod'>      

可以想象,Python世界裡的東西都是”灰色“的,解釋器對它們”一視同仁“,從來不以貌取人,隻看他們現在身上的标簽是什麼~

選擇結構

Python的選擇結構以if開始。

bool

if必然要涉及bool值,Python bool的取值為True和False:

>>> type(1==1)
<type 'bool'>
>>> type(True)
<type 'bool'>
>>> type(False)
<type 'bool'>      

(上面好像忘了列出bool類型)

對于Number(int, long, float, complex),0在if條件上也是False:

>>> if 1:
...     print "true"
...
true
>>> if 0:
...     print "true"
... else:
...     print "false"
...
false
>>> if 0.0:
...     print "0.0 is true"
...
>>> if 0j:
...     print "0j is true"
...      

提示:Python是以代碼縮進區分代碼塊的

除此之外,空的string和空的集合(tuple, list, set)也是False:

>>> if '':
...     print 'null string is true'
...
>>> if ():
...     print 'null tuple is true'
...
>>> if []:
...     print 'null list is true'
...
>>> if {}:
...     print 'null set is true'
...      

if, if-else & if-elif-else

上面幾個if示例多是隻有一個分支的,當然Python也支援多個分支的if:

>>> x = int(raw_input("Please enter an integer: "))
Please enter an integer: 42
>>> if x < 0:
...      x = 0
...      print 'Negative changed to zero'
... elif x == 0:
...      print 'Zero'
... elif x == 1:
...      print 'Single'
... else:
...      print 'More'
...
More
      

循環結構

Python的循環有for和while兩種,沒有do-while,也沒有loop-until。

for

Python的for循環和C的不同,它更像C++,Java裡的新式for循環:

>>> a = [1, 'two', 3.0]
>>> for i in a:
...     print i
...
1
two
3.0      

這種for疊代集合很友善。

但是要想像典型C語言的for循環那樣疊代一個整數區間怎麼辦?别怕,Python提供了内置(built-in)函數range(),它能傳回整數區間清單,供你疊代,用起來也很友善:

>>> for i in range(1, 6):
...     print i
...
1
2
3
4
5
>>> for i in range(10, 65, 10):
...     print i
...
10
20
30
40
50
60      

這裡展示了range的兩種調用形式,一種是range(a, b),它将傳回一個從a(包含a)到b(不包含)的整數清單(list),另一種range(a, b, s),将傳回一個a~b,以s為步長的list:

>>> range(1, 6)
[1, 2, 3, 4, 5]
>>> range(10, 65, 10)
[10, 20, 30, 40, 50, 60]      

while

Python的while循環和C的while差不多:

>>> i = 1
>>>
>>> while i < 5:
...     i = i+1
...     print i
...
2
3
4
5      

順便一提,Python裡 i=i+1 不能寫成i++,Python不支援這種文法;但可以寫成 i += 1:

>>> i
5
>>> i += 1
>>> i
6
>>> i++
  File "<stdin>", line 1
    i++
      ^
SyntaxError: invalid syntax
>>> ++i
6
>>> i
6      

各位可能會疑惑,為什麼++i可以?因為pyhon支援前置的+(正負号)運算,++被當做兩次正運算了;同理,+++i,++++i都是一樣的;我們可以順便測一下負号運算:

>>> i
6
>>> +++i
6
>>> ++++i
6
>>> -i
-6
>>> --i
6
>>> ---i
-6      

和想象的結果一緻,Great!

輸入輸出(IO)

當你想動手寫點”更有意思“的小程式的時候,你會發現除了三大基本控制結構和資料類型之外,你最需要的可能就是IO功能。

Q: 輸出可以用print,那麼輸入呢?是input嗎?

A:input可以,但更多時候需要用的可能是raw_input和readline這兩個built-in function,但readline僅适用于Unix平台.

Q:那麼input和raw_input有什麼差別呢?

A:來看看我和解釋器的下面這段互動,看看你能不能自己發現它們的不同。

>>> varA = raw_input('please input:')
please input:Life is too short, you need Python!
>>> varA
'Life is too short, you need Python!'
>>> type(raw_input('input something:'))
input something:asdf
<type 'str'>
>>> type(raw_input('input something:'))
input something:123
<type 'str'>
      

A:你看到了,raw_input不論你輸入什麼都會傳回str類型,這也是為什麼叫做raw_input的原因。

A: 繼續往下,你會看到input:

>>> type(input('input sth:'))
input sth:123
<type 'int'>
>>> type(input('input sth:'))
input sth:asdf
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
NameError: name 'asdf' is not defined
>>> type(input('input sth:'))
input sth:varA
<type 'str'>
>>> input('sth:')
sth:varA
'Life is too short, you need Python!'
>>> input('try some input like your code:')
try some input like your code:[1, 'two', 3.0]
[1, 'two', 3.0]
>>> input('try again:')
try again:'Oh!!!'
'Oh!!!'