目的:了解Python基本語法


資料型別

整數(int)


In [1]:
a=1

In [2]:
type(a)


Out[2]:
int

In [3]:
b=3

In [4]:
type(b)


Out[4]:
int

兩整數相除,輸出結果為浮點數(float)。(備註:Python 3開始)


In [5]:
a/b


Out[5]:
0.3333333333333333

In [6]:
type(a/b)


Out[6]:
float

在Python3,兩整數相除,需以//運算子來相除,方能真正用整數儲存該結果。


In [7]:
a//b


Out[7]:
0

In [8]:
type(a//b)


Out[8]:
int

兩整數相加,其輸出仍然為整數。


In [9]:
a+b


Out[9]:
4

In [10]:
type(a+b)


Out[10]:
int

浮點數(float)

Python不需宣告型別。一個數字將會被判別為整數(int)或浮點數(float),需看該數是否有小數點存在。


In [11]:
type(1)


Out[11]:
int

In [12]:
type(1.)


Out[12]:
float

In [13]:
type(1.E-5)


Out[13]:
float

字串(str)


In [14]:
mystr='Hello World!'

In [15]:
type(mystr)


Out[15]:
str

將該字串所有字變成大寫


In [16]:
mystr.upper()


Out[16]:
'HELLO WORLD!'

將該字串所有字變成小寫


In [17]:
mystr.upper().lower()


Out[17]:
'hello world!'

取出該字串前三個字


In [18]:
mystr[0:3]


Out[18]:
'Hel'

檢查某字串片段是否存在於該字串


In [19]:
'Wor' in mystr


Out[19]:
True

In [20]:
'WOR' in mystr


Out[20]:
False

In [21]:
'WOR' in mystr.upper()


Out[21]:
True

以len()看字串長度


In [22]:
len(mystr)


Out[22]:
12

In [23]:
mystr='   hi   '

清除左右空白


In [24]:
mystr.strip()


Out[24]:
'hi'

清除左空白


In [25]:
mystr.lstrip()


Out[25]:
'hi   '

清除右空白


In [26]:
mystr.rstrip()


Out[26]:
'   hi'

置換字串內的h成f


In [27]:
mystr.replace('h','f')


Out[27]:
'   fi   '

布林(Boolean)


In [28]:
t=True #真
f=False #假

In [29]:
t==f  #真等於假?


Out[29]:
False

In [30]:
t==t  #真等於真?


Out[30]:
True

In [31]:
t!=f  #真不等於假?


Out[31]:
True

In [32]:
t==f or t!=f   #真等於假 或是 真不等於假?


Out[32]:
True

In [33]:
t==f and t!=f  #真等於假 和 真不等於假?


Out[33]:
False

In [34]:
not t  #非真?


Out[34]:
False

for-loop


In [35]:
for j in range(5):
    print(j)


0
1
2
3
4

以上,我們使用了range()這個內建函數,它到底是什麼?


In [36]:
r=range(5)
print( type(r) )


<class 'range'>

用type()檢查變數r的型別,我們發現了r=range(5)是屬於'range'這個類別的一個物件。

接下來,我們以內建函數hasattr()去檢查range(5)這個物件是不是可疊代(iterable):

首先以help()函數檢查一下hasattr()的用法:


In [37]:
help(hasattr)


Help on built-in function hasattr in module builtins:

hasattr(obj, name, /)
    Return whether the object has an attribute with the given name.
    
    This is done by calling getattr(obj, name) and catching AttributeError.


In [38]:
hasattr(range(5), '__iter__')


Out[38]:
True

In [39]:
r=range(5).__iter__()        # 取得range(5)的疊代器
print( r.__next__() )        # 進行疊代並印出
print( r.__next__() )        # 進行疊代並印出
print( r.__next__() )        # 進行疊代並印出
print( r.__next__() )        # 進行疊代並印出
print( r.__next__() )        # 進行疊代並印出
print( r.__next__() )        # 進行疊代並印出


0
1
2
3
4
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-39-5dd2806f4c0e> in <module>()
      5 print( r.__next__() )        # 進行疊代並印出
      6 print( r.__next__() )        # 進行疊代並印出
----> 7 print( r.__next__() )        # 進行疊代並印出

StopIteration: 

小結

  1. 若物件(object)為可疊代(iterable):
    • 表示我們可用__iter__()以及__next__()來操控該物件,一個一個的去取得物件裡面的元素。
    • 物件裡面的元素亦可簡單的以for迴圈來取得。
  2. 複習以下函數的意義:hasattr(),__iter__(),__next__(),range()

while-loop


In [40]:
i=0
while(i<5):
    print(i)
    i+=1      # i=i+1的簡寫


0
1
2
3
4

常用於不確定要跑幾次,要跑到直到條件滿足才跳出迴圈的情形。例如:嘗試擷取某網頁,直到失敗次數太多或是擷取成功為止。

清單(list)

定義:包含元素的一個集合。清單內的元素可重複,且每個元素都有一個索引(index)。


In [41]:
array=[1,2,2,3,4,5]  #建立一個清單
print(array)
print(array[0])      #印出清單內的第一個元素
print(array[-1])     #印出清單內最後一個元素


[1, 2, 2, 3, 4, 5]
1
5

In [42]:
type([1,2,2,3,4,5]) #以type查看清單型別,確定清單(list)的型別就是list。


Out[42]:
list

In [43]:
hasattr([1,2,3,4,5],'__iter__') # 若是[1,2,3,4,5]為可疊代物件,那我們就可以用迴圈來疊代出清單內的所有元素。


Out[43]:
True

In [44]:
for j in [1,2,3,4,5]:
    print(j,j**2)


1 1
2 4
3 9
4 16
5 25

In [45]:
for j in [1,2.,'字串',3,range(10),5,[1,1,1,2,2,2]]:
    print(j,'\t',type(j),'\t',hasattr(j,'__iter__'))


1 	 <class 'int'> 	 False
2.0 	 <class 'float'> 	 False
字串 	 <class 'str'> 	 True
3 	 <class 'int'> 	 False
range(0, 10) 	 <class 'range'> 	 True
5 	 <class 'int'> 	 False
[1, 1, 1, 2, 2, 2] 	 <class 'list'> 	 True

從以上得知:

  1. 清單裡的元素可以有不同的型別(type)。
  2. 字串(str)和清單(list)一樣,是可以疊代的物件。因此,他們可以用for迴圈來進行內容的提取,例如:

In [46]:
for j in 'Python':
    print(j)


P
y
t
h
o
n

使用append()添加新元素至清單內


In [47]:
array=[1,2,3]
array.append(4)
print(array)


[1, 2, 3, 4]

使用del 刪除清單內元素


In [48]:
print(array)
del array[2]  #刪除清單內的第二個元素
print(array)


[1, 2, 3, 4]
[1, 2, 4]

我們可使用len()去得知清單的長度


In [49]:
array=[10,20,30,40]
print(len(array))


4

使用enumerate()去列舉清單


In [50]:
enumerate(array)


Out[50]:
<enumerate at 0x7ff5541025a0>

In [51]:
type(enumerate(array))


Out[51]:
enumerate

In [52]:
hasattr(enumerate,'__iter__')


Out[52]:
True

In [53]:
for j in enumerate(array):
    print(j)


(0, 10)
(1, 20)
(2, 30)
(3, 40)

In [54]:
print(  type( (0,10) ) )


<class 'tuple'>

tuple是什麼?


In [55]:
array=(1,2,3,"abc")
print(array)


(1, 2, 3, 'abc')

In [56]:
del array[1]


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-56-811224d29713> in <module>()
----> 1 del array[1]

TypeError: 'tuple' object doesn't support item deletion

In [57]:
array.append(5)


---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-57-02b372a4b65b> in <module>()
----> 1 array.append(5)

AttributeError: 'tuple' object has no attribute 'append'

In [58]:
array[2]=0


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-58-cefb8d0a519b> in <module>()
----> 1 array[2]=0

TypeError: 'tuple' object does not support item assignment

結論:不可新增刪除覆蓋tuple內的元素,因此tuple可以被看做是唯讀的list。

list可以被取set()。

set的定義:集合內元素不允許重複,且集合內的元素無索引。


In [59]:
set([1,1,2,3,3,4,1,2,'alpha','beta'])


Out[59]:
{1, 2, 3, 4, 'beta', 'alpha'}

In [60]:
type( {1, 2, 3, 4, 'beta', 'alpha'} )


Out[60]:
set

In [61]:
st={1,1,2,3,3,4,1,2,'alpha','beta'}
print(st)
print(hasattr(st,'__iter__'))


{1, 2, 3, 4, 'beta', 'alpha'}
True

In [62]:
for j in st:
    print(j)


1
2
3
4
beta
alpha

In [63]:
print(st[0])


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-63-55c26b6e8a4b> in <module>()
----> 1 print(st[0])

TypeError: 'set' object does not support indexing

也就是先前說的,set內的元素並無索引。

Python特殊的清單處理方式

將range(5)裡面的東西抓出來,放到一清單叫做lst,可有各種寫法:

第一種


In [64]:
lst=[]
for j in range(5):
    lst.append(j)
print(lst)


[0, 1, 2, 3, 4]

第二種


In [65]:
lst=[j for j in range(5)]   #此是非常Python的寫法(Pythonic way of coding)
print(lst)


[0, 1, 2, 3, 4]

第三種


In [66]:
lst=list(range(5))
print(lst)


[0, 1, 2, 3, 4]

第四種


In [67]:
lst=[*range(5)]
print(lst)


[0, 1, 2, 3, 4]

練習0-1. 運用range(5),for以及append()建立一清單,其內容為[0,1,4,9,16]


In [68]:
#法一:
lst=[]
for j in range(5):
    #完成接下來的部分


  File "<ipython-input-68-d813af186245>", line 4
    #完成接下來的部分
             ^
SyntaxError: unexpected EOF while parsing

In [69]:
#法二:
#提示: lst=[.....]

練習0-2. 運用range(5), if以及for建立一清單,其內容為[0,4,16]


In [70]:
# 法一:
lst=[]
for j in range(5):
    #完成接下來的部分


  File "<ipython-input-70-8d48153b1e33>", line 4
    #完成接下來的部分
             ^
SyntaxError: unexpected EOF while parsing

In [71]:
#法二:
#提示: lst=[.....]

if的用法

if...elif..else的使用 :


In [72]:
x=5

if(x==1):
    print('x is 1')
elif(x==2):
    print('x is 2')
else:
    print('x is neither 1 nor 2.')


x is neither 1 nor 2.

例:取range(10)內的偶數並印出:

法一


In [73]:
for j in range(10):
    if(j%2==0):
        print(j)


0
2
4
6
8

法二


In [74]:
[j for j in range(10) if j%2==0]


Out[74]:
[0, 2, 4, 6, 8]

以if控制迴圈的break和continue


In [75]:
for j in range(5):
    print(j)
    if(j==2):
        break      #中斷,跳出迴圈


0
1
2

In [76]:
for j in range(5):
    if(j==2):
        continue  #略過以下程式碼,並繼續疊代至下一個元素
    print(j)


0
1
3
4

練習1. 試著輸出以下內容

1 1 1 1 2 2 1 3 3 1 4 4 1 5 5 2 1 2 2 2 4 2 3 6 2 4 8 2 5 10 3 1 3 3 2 6 3 3 9 3 4 12 3 5 15

In [77]:
#提示:使用for, range(),print()

for i in range(1,4):
    #完成接下來的部分


  File "<ipython-input-77-5042f5bdc6bc>", line 4
    #完成接下來的部分
             ^
SyntaxError: unexpected EOF while parsing

練習2. 試著輸出以下內容

[1, 2, 3, 4, 5, 6, 7, 8, 9] [2, 4, 6, 8, 10, 12, 14, 16, 18] [3, 6, 9, 12, 15, 18, 21, 24, 27] [4, 8, 12, 16, 20, 24, 28, 32, 36] [5, 10, 15, 20, 25, 30, 35, 40, 45] [6, 12, 18, 24, 30, 36, 42, 48, 54] [7, 14, 21, 28, 35, 42, 49, 56, 63] [8, 16, 24, 32, 40, 48, 56, 64, 72] [9, 18, 27, 36, 45, 54, 63, 72, 81]

In [78]:
#提示:使用for, range(),print(),以及建立一個清單(list)
#完成接下來的部分

函數:將計算結果直接於函數內印出或回傳(return)出函數外

例一


In [79]:
def square(x):
    print(x*x)

In [80]:
def square_return(x):
    return(x**2)

square(x)將只會印出x, 而square_return(x)將會回傳x。


In [81]:
square(2)


4

In [82]:
square_return(2)


Out[82]:
4

可另一變數res接收square_return(x)回傳的值。


In [83]:
res=square_return(2)

In [84]:
print(res)


4

需注意的是,square(x)並不會回傳值,因此res將接收到None(無)。


In [85]:
res=square(2)


4

In [86]:
print(res)


None

例二: 寫一個函數add(a, b)。其輸入為 a和b,輸出為 a+b。


In [87]:
def add(a,b):
    return a+b

In [88]:
addResult=add(5,7)
print(addResult)


12

複習:Java函數寫法(輸入x,回傳x平方)


In [89]:
%%file testSquare.java
public class testSquare{
    public static void main(String args[]){
        int y=square(2);
        System.out.println(y);
    }
    
    static int square(int x){
        return x*x;
    }
}


Writing testSquare.java

In [90]:
!javac testSquare.java
!java testSquare


4

練習3:寫一個函數factorial(n)。

其作用為:

輸入:$n$,輸出:$1*2*3*....*n$


In [91]:
# 修改以下程式碼,以完成函數factorial(n)
def factorial(n):
    if(n==0):
        return ???
    if(n!=0):
        return ???


  File "<ipython-input-91-83c44308df6d>", line 4
    return ???
           ^
SyntaxError: invalid syntax

匿名函數

一般函數寫法


In [92]:
def f(x,y):
    return x+y

In [93]:
f(1,2)


Out[93]:
3

使用匿名函數,並將匿名函數給予名稱f。此方法得到的函數等同於上述使用一般函數寫法的結果。


In [94]:
f=lambda x,y:x+y

In [95]:
f(1,2)


Out[95]:
3

將匿名函數直接拿來使用,不給名稱,用完就丟。


In [96]:
(lambda x,y:x+y)(1,2)  # 1+2=3


Out[96]:
3

In [97]:
(lambda x:x*x)(7)      # 7X7=49


Out[97]:
49

物件導向範例

範例:提款機


In [98]:
class Customer(object):
    def __init__(self, name, balance=0.0):
        self.name=name             #當物件被新建立,姓名以及餘額兩個屬性將被初始化
        self.balance=balance

    def withdraw(self, amount):    #提款
        if amount > self.balance:  #若要提取大於帳戶餘額的數目,將提出錯誤訊息
            raise RuntimeError('Amount greater than available balance.')
        self.balance -= amount
        return self.balance
    
    def deposit(self, amount):     #存款
        self.balance += amount
        return self.balance
  • 第1行:所有Python3類別都是object這個類別的子類別。
  • 第2行:當物件產生時,初始子init()(等同Java中的建構子)將初始化屬於該物件的一些屬性。此範例中,屬於該物件的兩個屬性,也就是人名和帳戶餘額將被建立。
  • 所有方法都要接收物件本身為第一個參數。依照慣例,大家將該物件本身稱作self。

In [99]:
a=Customer("Bill",100)
a.withdraw(70)


Out[99]:
30

In [100]:
a.deposit(60)


Out[100]:
90

In [101]:
a.withdraw(100)


---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-101-c8963c03a85e> in <module>()
----> 1 a.withdraw(100)

<ipython-input-98-efdfd8238341> in withdraw(self, amount)
      6     def withdraw(self, amount):    #提款
      7         if amount > self.balance:  #若要提取大於帳戶餘額的數目,將提出錯誤訊息
----> 8             raise RuntimeError('Amount greater than available balance.')
      9         self.balance -= amount
     10         return self.balance

RuntimeError: Amount greater than available balance.

NumPy (Python中用於處理numerical array的套件)

此套件用於建立數值陣列和做數值運算。


In [102]:
import numpy as np

內建常數$\pi$


In [103]:
np.pi


Out[103]:
3.141592653589793

計算根號$\pi$


In [104]:
np.sqrt(np.pi)


Out[104]:
1.7724538509055159

一維序列

用np.arange(n)建立一序列內容為[0 1 2 .....n-1]


In [105]:
np.arange(10)


Out[105]:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

用np.linspace(0,2.*np.pi,10)建立一個一維線性空間。起始為0,終點為 $\pi$ ,共10個點。


In [106]:
np.linspace(0,2.*np.pi,10)


Out[106]:
array([ 0.        ,  0.6981317 ,  1.3962634 ,  2.0943951 ,  2.7925268 ,
        3.4906585 ,  4.1887902 ,  4.88692191,  5.58505361,  6.28318531])

將數列內所有數值+100


In [107]:
np.arange(10)+100


Out[107]:
array([100, 101, 102, 103, 104, 105, 106, 107, 108, 109])

將數列內所有數值取平方


In [108]:
np.arange(10)**2


Out[108]:
array([ 0,  1,  4,  9, 16, 25, 36, 49, 64, 81])

以np.mean()計算出算數平均


In [109]:
np.mean( np.arange(10) )


Out[109]:
4.5

以np.std()計算出標準差


In [110]:
np.std( np.arange(10) )


Out[110]:
2.8722813232690143

檢驗Numpy序列和Python清單效能差異


In [111]:
a=np.random.normal(0,1,100000) # 100000個常態分佈亂數
b=np.random.normal(0,1,100000) # 100000個常態分佈亂數

list_a=list(a)
list_b=list(b)

In [112]:
%%timeit
res=a+b


51.8 µs ± 51.1 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [113]:
%%timeit

res=[] 
for j in range(len(list_a)):
    res.append(list_a[j]+list_b[j])


14.2 ms ± 20 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

NumPy較快,因

  • 有做vectorization (能把資料一次餵給多個算數邏輯閘,以加快運算速度。)
  • array裡的資料皆同型別,相加時不用一個個做型別判別。

二維矩陣

建立一矩陣


In [114]:
A=np.array([[1,2,3],[4,5,6],[7,8,9]])

In [115]:
A


Out[115]:
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

將$A$轉置 ($A^{T}$)


In [116]:
A.T


Out[116]:
array([[1, 4, 7],
       [2, 5, 8],
       [3, 6, 9]])

$A\cdot A^{T}$


In [117]:
A.dot(A.T)


Out[117]:
array([[ 14,  32,  50],
       [ 32,  77, 122],
       [ 50, 122, 194]])

截取片段:清單方式:以A [index0][index1] 取出二維陣列$A$的部分片段。


In [118]:
A[0]


Out[118]:
array([1, 2, 3])

In [119]:
A[1:3]


Out[119]:
array([[4, 5, 6],
       [7, 8, 9]])

In [120]:
A[1:3]


Out[120]:
array([[4, 5, 6],
       [7, 8, 9]])

In [121]:
A[:][1:3]


Out[121]:
array([[4, 5, 6],
       [7, 8, 9]])

截取片段:矩陣方式:以A [index0,index1] 取出二維陣列$A$的部分片段。(index0方向:垂直,index1方向:水平)


In [122]:
A


Out[122]:
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

In [123]:
A[1:3,:]


Out[123]:
array([[4, 5, 6],
       [7, 8, 9]])

In [124]:
A[:,1:3]


Out[124]:
array([[2, 3],
       [5, 6],
       [8, 9]])

檢查一下A的形狀


In [125]:
A.shape


Out[125]:
(3, 3)

以條件找尋A裡面符合條件的數值


In [126]:
A>5


Out[126]:
array([[False, False, False],
       [False, False,  True],
       [ True,  True,  True]], dtype=bool)

In [127]:
A[A>5]


Out[127]:
array([6, 7, 8, 9])

練習4: 建立一函數 f。輸入: 一個 2 維矩陣,輸出: 該2維矩陣內的所有數值加總。


In [ ]:
A=np.array([[1,2,3],[4,5,6],[7,8,9]])

In [ ]:
def f(A)
    # 完成此函數
    return ???