Python 基礎語法

AIC x PyLadies Taiwan

Author : Mars
Speaker : 米卡

2018/05/04



Part I - Roadmap

  • Python 簡介
  • 開發環境介紹
  • 變數
  • 字串
  • 輸入與輸出
  • 判斷式

Python 簡介

  • Python是一種物件導向、直譯式的電腦程式語言
  • 語法簡單,簡潔易懂
  • 可以做很多事情...

應用

  • [網路爬蟲]:urllib、requests、lxml、beautiful_soup、scrapy、selenium
  • [資料庫串接]:sqlite3(sqlite)、MySQLdb(MySQL)、pymssql(MSSQL)、Psycopg(PostgreSQL)
  • [自然語言]:NLTK、jieba
  • [統計應用]:pandas、numpy、scipy、matplotlib
  • [機器學習]:scikit-learn、TensorFlow
  • [影像處理]:PIL、opencv
  • [網站架設]:Django、Flask
  • [網路分析]:scapy
  • [GUI設計]:tkinter、PyQt
  • [軟硬整合]:raspberry pi 樹莓派、Arduino
  • [遊戲開發]:pygame
  • [App開發]:kivy
  • [各種服務的API串接]:Bot

開發環境介紹

使用jupyter撰寫&執行 第一隻Python 程式

  • 新增一個Notebook (New > Notebooks | Python [default]) title

  • 輸入程式碼 print ("Hello PyLadies"),按下介面上的 >| 或是用快捷鍵 Ctrl+Enter、Shift+Enter編譯執行

In [10]:
print ("Hello PyLadies")
Hello PyLadies

!注意

  • 如果有用到上方cell的程式碼內容,需要先編譯執行上方cell的程式碼
  • 如果針對現在的cell多次編譯執行,並不會影響到上方cell已編譯執行後的結果

變數

  • 變數是一個容器,是資料的儲存空間
  • 在程式中「=」是「賦值」的意思:將右邊的資料儲存到左邊的變數
  • my_score、pi、url 都是自行命名的變數
  • 可以命名的字元:_、0~9、a~Z

!注意

  • 不能以數字開頭
  • 不能與保留字相同 (ex: import, for, in, str....)
  • 大小寫有別
  • 好的命名方式會讓程式碼容易閱讀

變數型別

  • type(變數):印出此變數的型別
In [12]:
my_score = 96
pi = 3.14159
url = "http://blog.marsw.tw"

print (type(my_score))
print (type(pi))
print (type(url))
<class 'int'>
<class 'float'>
<class 'str'>

Python 是一個動態性的語言

  • 同樣的變數可以隨時更動他的變數型別
In [2]:
my_score = 96
print (type(my_score))

my_score = 96.0
print (type(my_score))

my_score = "96"
print (type(my_score))
<class 'int'>
<class 'float'>
<class 'str'>

數值

  • 整數 integer:int
  • 小數 float:float
  • 運算元:+ - * / % **
In [6]:
a = 96
b = 80
c = a+b
print (a+b,c)
print (a-b)
176 176
16
In [4]:
print (10*3)  # 乘法
print (10/3)  # 除法
print (10%3)  # 取餘數
print (10**3) # 次方
30
3.3333333333333335
1
1000

運算元的簡潔寫法

  • a+= b : a = a+b
  • a-= b : a = a-b
  • a*= b : a = a*b
In [7]:
count = 0
count+= 1 
print (count) # count = 1
count*= 3
print (count) # count = 3
count-= 2
print (count) # count = 1
1
3
1

字串(string)

  • 可以直接給定詞句
  • 也可以給空白句
  • 可以相+、相*
In [10]:
my_string = "Hi"
my_string2 = ""
my_string2 = my_string2 + "Py" + 'Ladies'
my_string3 = "Hello"*4

print (my_string)
print (my_string2)
print (my_string3)
Hi
PyLadies
HelloHelloHelloHello

!注意

  • 用「成對的」雙引號( " ) 或是單引號( ' ) ,將字串包住

!注意

  • 字串與數值不可一同運算
In [11]:
my_string = "123"
my_int_number = 456
print (my_string+my_int_number) # TypeError: must be str, not int
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-11-151fbba3d316> in <module>()
      1 my_string = "123"
      2 my_int_number = 456
----> 3 print (my_string+my_int_number)

TypeError: must be str, not int

型別轉換

  • int(物件):將物件轉成整數(integer)型別
  • float(物件):將物件轉成浮點數(float)型別
  • str(物件):將物件轉成字串(string)型別

!注意

  • 字串轉數字,需要符合整數、浮點數的格式
In [15]:
input1 = 123
input2 = "456"
input3 = "5566.123"
print (str(input1)+input2)  #str+str
print (input1+int(input2))  #123+456=579
print (float(input3)+input1)  #5566.123+123=5689.123
print (int(input3))          # ValueError: invalid literal for int() with base 10: '5566.123'
123456
579
5689.123
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-15-6190e6493407> in <module>()
      5 print (input1+int(input2))  #123+456=579
      6 print (float(input3)+input1)  #5566.123+123=5689.123
----> 7 print (int(input3))

ValueError: invalid literal for int() with base 10: '5566.123'

輸入與輸出

  • input(提示字):從鍵盤輸入值
    • 輸入的值會儲存為字串型別
  • print(物件):輸出物件到螢幕上
    • 可以用 , 印出多個物件(印出後,會以空格分隔物件)
In [16]:
a = input("a=")    # "a=" 是提示字,讓我們知道電腦在等我們輸入
b = input("b=")
print ("a+b=",a+b) # input進來是字串
a=5
b=2
a+b= 52
In [17]:
a = input("a=")    # "a=" 是提示字,讓我們知道電腦在等我們輸入
b = input("b=")
print ("a+b=",a+b) # input進來是字串
a=Hello
b=PyLadies
a+b= HelloPyLadies

input()可以讓我們跟電腦互動

而不單單只是讓電腦print()東西出來而已

互動的計算機

In [18]:
a = input("a=") # "a=" 是提示字,讓我們知道電腦在等我們輸入
a = int(a)      # input進來是字串,要做數值運算要用int()轉換   
# 以上也可以簡寫為 a = int(input("a="))
print ("a*2=",a*2)
print ("a^2=",a**2)
a=5
a*2= 10
a^2= 25

問候機器人

In [1]:
a = input("請問您是誰? ") 
print ("你好",a)      # 用,分隔會印出空格
print("你好"+a)     # 可以用字串相加,就不會有空格
請問您是誰? AIC
你好 AIC
你好AIC

判斷式:if/elif/else

  • if 是判斷式必備的
    • if:一種選項,滿足條件,才執行某動作
    • elif:有更多條件,滿足的話執行某動作,須伴隨 if 存在
    • else:當以上條件都不滿足,執行某動作,須伴隨 if 存在
  • if 布林型別: 如果布林型別 == True,就做這裡面的事情

if 語法:

In [ ]:
if lists[0] == 0:
    ... 
elif lists[0] == 1:
    ... 
else lists[0] == 2:
    ...
In [22]:
# 基本的判斷式是由 if 構成
a = 61
if a>=60:
    print ("及格")
及格
In [23]:
# 不符合條件,因此什麼都沒有印出
a = 58
if a>=60:
    print ("及格")
In [24]:
# 如果希望處理判斷條件之外的狀況,可以用else
a = 58
if a>=60:
    print ("及格")
else:
    print ("不及格")
不及格

如果有很多個條件,一個 if 不夠用,可以用 elif

In [25]:
a = 11
b = 8
if a>b:
    print ("a>b")
elif a<b:
    print ("a<b")
else:
    print ("a<=b")
print ("這是判斷式外的區塊")
a>b
這是判斷式外的區塊

!注意

  • Python是靠「縮排」(四個空格),來斷定程式碼屬於那一個區塊。
  • if/elif/else 後面記得要有冒號(:)
In [26]:
a = 11
b = 8
# 第1組判斷式
if a%2==0:
    print ("a is even")
# 第2組判斷式
if a>b:
    print ("a>b")
elif a<b:
    print ("a<b")
else:
    print ("a==b")
a>b
  • 一個 if 就是一組判斷式
  • 兩組判斷式是不互相影響的
    • 如果 a = 11, b = 8 ,
      • 第1組判斷式沒有符合任何條件就什麼事都不會做,
      • 第2組判斷式會印出a>b,不受到第1組判斷式沒有任何條件符合的影響
    • 如果 a = 6, b = 8 ,
    • 第1組判斷式會印出a is even,
    • 第2組判斷式會印出a<b

[補充] - 條件運算式

x if y else z:當y為True,運算的結果是 x,否則是 z

In [27]:
# 如果x是奇數,就保留原值,否則-1
x = 9
result = x if (x%2==1) else x-1  
print(result)
9


Part II - Roadmap

  • 序列型別
  • 序列共同介面
  • 序列的應用

[ 序列型別 ]

常見序列型別有 字串(string)、串列(list)、元組(tuple)

title

串列(list)

  • 可以直接給定有值的串列
  • 也可以給空串列
  • 可以相+、相*

!注意

  • 串列的組成可以不必都是同樣類型的元素
In [29]:
my_list1 = ["a",2016,5566,"PyLadies"]
my_list2 = []
my_list3 = my_list1+[2016,2016.0]
my_list4 = [1,2,3]*3
print (my_list1,bool(my_list1))
print (my_list2,bool(my_list2))
print (my_list3)
print (my_list4)
['a', 2016, 5566, 'PyLadies'] True
[] False
['a', 2016, 5566, 'PyLadies', 2016, 2016.0]
[1, 2, 3, 1, 2, 3, 1, 2, 3]

存取串列元素

  • my_list[ i ]:取得索引(index)在 i 的元素
  • 索引可以是負數,如果是索引為 -i,會被當作拿取索引為「串列長度-i」的元素

!注意

  • Python 是從 0 開始數
In [30]:
# 索引值     0 , 1  ,  2 ,    3     ,  4 ,  5   
my_list = ["a",2016,5566,"PyLadies",2016,2016.0] # 這是一個長度為6的串列
print ("The 4th  element",my_list[3])
print ("The last element",my_list[-1])           # 等同於拿取索引=6-1=5的元素
print ("The second-last element",my_list[-2])    # 等同於拿取索引=6-2=4的元素
The 4th  element PyLadies
The last element 2016.0
The second-last element 2016
In [31]:
# 索引值     0 , 1  , 2 ,    3     ,  4 ,  5  
my_list = ["a",2016,5566,"PyLadies",2016,2016.0]
b = my_list[1]
my_list[2] = 2017
print(b)
print(my_list)
2016
['a', 2016, 2017, 'PyLadies', 2016, 2016.0]

「字串」跟「串列」很像

  • 字串的每個元素都是一個字元(字母或符號)
  • 用同樣的方式存取元素
In [32]:
# 索引值     0123456789....
my_string = "PyLadies Taiwan"
print ("The 1st  element of my_string = ",my_string[0])
print ("The 8th  element of my_string = ",my_string[7])
print ("The last element of my_string = ",my_string[-1]) 
The 1st  element of my_string =  P
The 8th  element of my_string =  s
The last element of my_string =  n

!注意

  • 索引不能超過界線
In [35]:
print(my_string[20])
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-35-071b8d4e8c76> in <module>()
----> 1 print(my_string[20])

IndexError: string index out of range

「元組(tuple)」跟「串列」更像

  • 元組是不能修改的串列

!注意

  • 因為小括號 ( ) 會被當成調整運算元的優先順序,所以只有一個元素的元組,要多加 ,
In [39]:
my_tuple1 = ("a",2016,5566,"PyLadies")
my_tuple2 = ()
my_tuple3 = my_tuple1+(2016,2016.0)
my_tuple4 = (1,2,3)*3
my_tuple5 = (1,)  # 加 ,
my_int    = (1)   # 不加 ,
print (my_tuple1,bool(my_tuple1))
print (my_tuple2,bool(my_tuple2))
print (my_tuple3)
print (my_tuple4)
print (my_tuple5)
print (type(my_tuple5))  # <class 'tuple'>
print (my_int)
print (type(my_int))  #<class 'int'>
print (my_tuple1[1])
('a', 2016, 5566, 'PyLadies') True
() False
('a', 2016, 5566, 'PyLadies', 2016, 2016.0)
(1, 2, 3, 1, 2, 3, 1, 2, 3)
(1,)
<class 'tuple'>
1
<class 'int'>
2016

型別轉換

In [43]:
s = "PyLadies"                 # <class 'str'>
l = ["a",2016,5566,"PyLadies"] # <class 'list'> 
t = ("a",2016,5566,"PyLadies") # <class 'tuple'>
print(type(list(t)))
print(type(tuple(l)))
print(list(s))
print(tuple(s))
<class 'list'>
<class 'tuple'>
['P', 'y', 'L', 'a', 'd', 'i', 'e', 's']
('P', 'y', 'L', 'a', 'd', 'i', 'e', 's')

比較運算

  • 從第1個元素開始比,如果一樣就再比第2個元素...,直到不一樣就停止比對。
  • 如果元素型別不同,會出現錯誤!
In [44]:
s1 = "Hi"
s2 = "Hello" 
print(s1<s2) # i 的 ASCII 比 e 大
False
In [45]:
l1 = ["a",2016,5566,"PyLadies"]
l2 = ["a",2016,5566,"PyLadies"]
print(l1==l2)
l2+= [2017]
print(l2>l1,l2)
True
True ['a', 2016, 5566, 'PyLadies', 2017]
In [46]:
l3 = ["a",2016,"PyLadies"]
print(l1<l3)  # 如果元素型別不同,會出現錯誤!
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-46-5b31c0361295> in <module>()
      1 l3 = ["a",2016,"PyLadies"]
----> 2 print(l1<l3)

TypeError: '<' not supported between instances of 'int' and 'str'

[ 序列共同介面 ]

前面提到的利用 序列 [索引] 存取元素,也是共同介面之一!

序列長度

len(s)

In [47]:
my_string = "PyLadies Taiwan"
my_list = ["a",2016,5566,"PyLadies",2016,2016.0]
print ("Length of my_string = ",len(my_string))
print ("Length of my_list = ",len(my_list))
Length of my_string =  15
Length of my_list =  6

數值計算

  • max(串列):序列中最大值
  • min(串列):序列中最小值
  • sum(串列):序列總和,針對全數字序列才有用
In [49]:
l = [3, 4, 2.1, 1]
t = (3, 4, 2.1, 1)
s = "PyLadies"    # ASCII=>  A = 65 ; a = 97 
print(max(l),min(l),sum(l))
print(max(t),min(t),sum(t))
print(max(s),min(s))
print(sum(s))
4 1 10.1
4 1 10.1
y L
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-49-d91b8caf788d> in <module>()
      5 print(max(t),min(t),sum(t))
      6 print(max(s),min(s))
----> 7 print(sum(s))

TypeError: unsupported operand type(s) for +: 'int' and 'str'

[練習]

統計全班的成績狀況:

  • 全班最高分與最低分的落差為?
  • 全班分數的平均為?
In [51]:
score_of_each_student = [85,70,54,87,98,66,40]
In [54]:
avg_score = sum(score_of_each_student) / len(score_of_each_student) # len=7
print ("全班分數落差為",max(score_of_each_student)-min(score_of_each_student))
print ("全班平均為",avg_score)
全班分數落差為 58
全班平均為 71.42857142857143

判斷序列中是否存在某元素

x in s、x not in s

In [55]:
my_string = "PyLadies Taiwan"

if "PyLadies" in my_string:
    print ("\"PyLadies\" found")
if "Python" in my_string:
    print ("\"Python\" found")
if "Taiwan" in my_string:
    print ("\"Taiwan\" found")
"PyLadies" found
"Taiwan" found
In [56]:
my_list = ["a",2016,5566,"PyLadies",2016,2016.0]
print(2016 in my_list)
print("2016" in my_list)
True
False

序列出現某元素的次數

s.count(x)

In [57]:
my_string = "PyLadies Taiwan"
my_list = ["a",2016,5566,"PyLadies",2016,2016.0]
print ("The time 'a' appears in my_string = ",my_string.count('a'))
print ("The time '2016' appears in my_string = ",my_list.count(2016))
The time 'a' appears in my_string =  3
The time '2016' appears in my_string =  3

[練習]

想想看要用什麼序列方法,找出以下這篇文章,出現幾次「in」

In [58]:
article = """
Bubble tea represents the "QQ" food texture that Taiwanese love. 
The phrase refers to something that is especially chewy, like the tapioca balls that form the 'bubbles' in bubble tea. 
It's said this unusual drink was invented out of boredom. 
"""
In [60]:
print (article.count('in'))
4

「in」的確在文章出現4次:someth"in"g、"in"、dr"in"k、"in"vented

但如果我們想要的是代表單字的「in」,就需要把文章分割,再來計算!

[ 序列的應用 ]

分割

串列 = 原字串.split(子字串,最多分割次數)

  • 將「原字串」以「子字串」切割,產生一個新的「串列」(不改變原本字串)
  • 最多分割次數預設為無限
In [61]:
s = "Hi PyLadies Taiwan"
l = s.split(" ")
print (l)
print (s.split(" ",1))
print (s)
print (l[0])
print (l[-1])
['Hi', 'PyLadies', 'Taiwan']
['Hi', 'PyLadies Taiwan']
Hi PyLadies Taiwan
Hi
Taiwan

[練習]

所以再想想看要用哪些序列方法,找出以下這篇文章,出現幾次單字「in」

  • 把文章切割成單字
  • 算出單字中,「in」出現幾次
In [62]:
article = """
Bubble tea represents the "QQ" food texture that Taiwanese love. 
The phrase refers to something that is especially chewy, like the tapioca balls that form the 'bubbles' in bubble tea. 
It's said this unusual drink was invented out of boredom. 
"""
In [63]:
word_of_article = article.split(" ")
print (word_of_article.count("in"))
1


Part III - Roadmap

  • 迴圈與迭代

[ 迴圈與迭代 ]

迭代的概念是「一個接著一個處理」, 需要有供給可迭代的物件的提供者,讓接收方一個個處理。

序列可以用索引值標示元素的概念,就是很好的提供者, 而處理這些迭代物件的接收方,在Python裡最常用的就是for迴圈!

[think]

  • 我想要輸入10個不相等的變數
  • 我想要輸入一串數組ex:(1,2,3,4,5),然後印出相加的總和
  • 我想要算出字串 "「1」、「5」、「7」、「3」、「2」、「6」" 出現數字的總和

while

  • 處理「未知」次數的重複狀況
  • while(條件成立): 執行某事

while 語法:

while lists[0] == 0: ...

In [2]:
# 輸入5個不相等的數字
my_list = []
while(len(my_list)<5):
    input_word = input("請輸入數字")
    input_num = int(input_word)
    if input_num not in my_list:  #判斷,不重複的數字才加入(append)一個元素x到List裡.
        my_list.append(input_num) 
    print (my_list)
請輸入數字1
[1]
請輸入數字2
[1, 2]
請輸入數字4
[1, 2, 4]
請輸入數字5
[1, 2, 4, 5]
請輸入數字4
[1, 2, 4, 5]
請輸入數字3
[1, 2, 4, 5, 3]

for

title

  • 處理「已知」次數的重複狀況
  • 命名物件指向每次從可迭代者拿出的元素
  • 重複要做的事是在迴圈裡面,所以要記得冒號、縮排
  • 迴圈會取出所有存在可迭代者中的元素。

for 語法:

for number in lists: ...

In [20]:
for i in [1,4,7,9]:
    print ('i=',i)
i= 1
i= 4
i= 7
i= 9

for 最方便的地方就是會自動拿取可迭代者下一個元素,直到無法拿取為止。

原理:會將可迭代者轉換成迭代器,然後用next方法,呼叫下一個元素。

In [3]:
my_list=[1,2,5,7,6]
for i in my_list:
    print (i)
1
2
5
7
6
In [4]:
for i in "Hello":
    print (i)
H
e
l
l
o

我想要算出字串 "「1」、「5」、「7」、「3」、「2」、「6」" 出現數字的總和

In [43]:
data = "「1」、「5」、「7」、「3」、「2」、「6」"
data = data.replace("「","")  # replace() 替換
data = data.replace("」","")
print (data)
print (data.split("、"))
1、5、7、3、2、6
['1', '5', '7', '3', '2', '6']
In [44]:
#接續
my_sum = 0
for i in data.split("、"):
    my_sum+=int(i)
    print (i,my_sum)
print ("The sum of list is",my_sum)
1 1
5 6
7 13
3 16
2 18
6 24
The sum of list is 24

[練習]

  • 輸入10個不重複的數字,印出其中為奇數的數字
    • 重複輸入數字
    • 如果輸入的數字存在串列中,則繼續輸入
    • 取得串列的各個元素
    • 如果餘數=1才印出

range(start,end,stride)

  • range也是一種序列型別,會回傳一系列能迭代的物件,是可迭代者
  • start 是 inclusive,預設是 0 開始
  • end 是 exclusive,必填值
  • stride 是跳幾次切割,預設是1
    • stride 為負值則由尾端向前端取,需讓start>end

注意!

  • start > end ,則等同於空
  • stride 不得為 0
In [3]:
print('range(5)     ',list(range(5)))     # 只有一個代表end
print('range(2,5)   ',list(range(2,5)))
print('range(2,5,2) ',list(range(2,5,2)))
print('range(5,0)   ',list(range(5,0)))    # start > end ,則等同於空
print('range(5,0,-1)',list(range(5,0,-1))) # stride 為負值則由尾端向前端取
print('range(0,5,-1)',list(range(0,5,-1))) # stride 為負值則由尾端向前端取,需讓start>end
range(5)      [0, 1, 2, 3, 4]
range(2,5)    [2, 3, 4]
range(2,5,2)  [2, 4]
range(5,0)    []
range(5,0,-1) [5, 4, 3, 2, 1]
range(0,5,-1) []
In [31]:
print (list(range(10)))
print (list(range(1,10)))
print (list(range(1,10,2)))
print (list(range(10,0,-1)))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 3, 5, 7, 9]
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
In [32]:
for i in range(1,5+1):
    print ("*"*i)
*
**
***
****
*****
In [35]:
for i in range(5,0,-1):
    print ("*"*i)
*****
****
***
**
*

配合迴圈,這樣可分別拿到0~2的數值,可以當成串列索引

In [5]:
print(list(range(3)))
for i in range(3):
    print(i)
[0, 1, 2]
0
1
2

想像我有一個紀錄員工年資的串列,薪水是依照 年資*100+22000 的公式去計算

In [6]:
# 土法煉鋼,一個個員工慢慢列
l = [5.5, 9, 10]
print("員工1的薪水",l[0]*100+22000)
print("員工2的薪水",l[1]*100+22000)
print("員工3的薪水",l[2]*100+22000)
# ...
員工1的薪水 22550.0
員工2的薪水 22900
員工3的薪水 23000

3個員工,我就要寫3行告訴我各個員工的薪水,那如果有100個員工...

如果有一個紀錄串列各個索引值0~n的資料型別,就會很方便

In [10]:
# 使用迴圈
l = [5.5, 9, 10]
for i in range(3):
    print("i=",i, "員工{}的薪水=>".format(i+1), l[i]*100+22000)
i= 0 員工1的薪水=> 22550.0
i= 1 員工2的薪水=> 22900
i= 2 員工3的薪水=> 23000
  • 串列也是一個可迭代者,
  • 如果要取所有串列的元素,除了用索引拿取 range(0,len(串列)),
  • 也可以直接用for迴圈處理:
In [11]:
l = [5.5, 9, 10]
for i in l:
    print(i)
5.5
9
10
In [12]:
l = [5.5, 9, 10]
for i in l:
    print(i*100+22000)
22550.0
22900
23000
In [13]:
# 對比 range() 寫法
l = [5.5, 9, 10]
for i in range(3):
    print(l[i]*100+22000)
22550.0
22900
23000

想要印出第幾位員工,因為直接用串列當成可迭代者,需要紀錄現在是第幾個索引(index)

In [15]:
l = [5.5, 9, 10]
count= 0         # 紀錄現在的索引(index)
for i in l:
    print("員工{}的薪水".format(count+1), i*100+22000)
    count+=1  # count = count+1 
員工1的薪水 22550.0
員工2的薪水 22900
員工3的薪水 23000
In [16]:
# 對比 range() 寫法
l = [5.5, 9, 10]
for i in range(3):
    print("員工{}的薪水".format(i+1), l[i]*100+22000)
員工1的薪水 22550.0
員工2的薪水 22900
員工3的薪水 23000

range( ) 更彈性的寫法

range(數值)中,數值最好保持彈性,
如果寫死,一但串列增加元素,就得改值,很不方便!

In [19]:
l = [5.5, 9, 10, 2.3] # 新增一個元素 -> 2.3
for i in range(4):
    print("員工{}的薪水".format(i+1), l[i]*100+22000)
員工1的薪水 22550.0
員工2的薪水 22900
員工3的薪水 23000
員工4的薪水 22230.0
In [25]:
l = [5.5, 9, 10, 2.3] # 新增一個元素 -> 2.3
#print(len(l))  --> 4
for i in range(len(l)): # 串列有多長就用多長
    print("員工{}的薪水".format(i+1), l[i]*100+22000)
員工1的薪水 22550.0
員工2的薪水 22900
員工3的薪水 23000
員工4的薪水 22230.0

[練習] 調分公式:開根號,再乘10

有一列學生的成績 l = [32,56,58,62,79,82,98]
我希望將學生調分:

學生1 56.568542494923804
學生2 74.83314773547883
學生3 76.15773105863909
學生4 78.74007874011811
學生5 88.88194417315589
學生6 90.55385138137417
學生7 98.99494936611666

Hint:

In [26]:
import math
print(math.sqrt(9))
print(math.sqrt(10))
3.0
3.1622776601683795
  • 練習一: 使用 range()
In [ ]:
l = [32,56,58,62,79,82,98]
import math
for i in range(__):
  print("學生{}".format(__),math.sqrt(___)*10)
  • 練習二: 使用串列,配合紀錄現在索引位置的物件
In [ ]:
l = [32,56,58,62,79,82,98]
import math
count = 0
for i in l:
  print("學生{}".format(__),math.sqrt(___)*10)
  count = _____

答案

In [5]:
#練習一: 使用 range()
l = [32,56,58,62,79,82,98]
import math
for i in range(len(l)):
  print("學生{}".format(i+1),math.sqrt(l[i])*10)

print("----------分隔線----------")

#練習二: 使用串列,配合紀錄現在索引位置的物件
l = [32,56,58,62,79,82,98]
import math
count = 0
for i in l:
  print("學生{}".format(count+1),math.sqrt(i)*10)
  count = count+1 # count+=1
學生1 56.568542494923804
學生2 74.83314773547883
學生3 76.15773105863909
學生4 78.74007874011811
學生5 88.88194417315589
學生6 90.55385138137417
學生7 98.99494936611666
----------分隔線----------
學生1 56.568542494923804
學生2 74.83314773547883
學生3 76.15773105863909
學生4 78.74007874011811
學生5 88.88194417315589
學生6 90.55385138137417
學生7 98.99494936611666


Part IV - Roadmap

  • 字典
  • 函式

字典 (Dictionary)

  • 字典名稱[key]: 字典以鍵值key去存取資料value
  • 鍵值key: 很像是串列的索引(index)
  • 查找速度快
  • 設定值: 字典名稱[key]=value
  • 拿取值: 字典名稱[key]
  • key:value
    {
      "the":10 ,
      "a"  :9  ,
      "of" :6  ,
      "in" :6
    }

!注意

  • 字典是「無順序排放」的資料型別
  • 字典是存key,然後以key去找資料value
  • key 不可重複
In [3]:
my_dict = {} #空字典
my_dict["the"] = 10
my_dict["a"] = 9
my_dict["of"] = 6
my_dict["in"] = 6
my_dict2 = {"the":10,"a":9,"of":6,"in":6}
print (my_dict)
print (my_dict2)
print (my_dict["the"])
{'the': 10, 'a': 9, 'of': 6, 'in': 6}
{'the': 10, 'a': 9, 'of': 6, 'in': 6}
10

!注意

  • 直接使用字典不存在的key去找資料會有錯誤!
In [6]:
#字典'存在'的 key
my_dict = {"the":10,"a":9,"of":6,"in":6}
print ("the" in my_dict)
print (my_dict["the"])
True
10
In [8]:
#字典'不存在'的 key
my_dict = {"the":10,"a":9,"of":6,"in":6}
print ("with" in my_dict)
print (my_dict["with"])
False
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-8-c0dcfc05aa13> in <module>()
      2 my_dict = {"the":10,"a":9,"of":6,"in":6}
      3 print ("with" in my_dict)
----> 4 print (my_dict["with"])

KeyError: 'with'

字典 - 以迴圈處理

  • 字典以鍵值key去存取資料value
In [16]:
my_dict = {"Mars":20,"姿君":25,"毛毛":10}
for key in my_dict:
    print(key,my_dict[key])
Mars 20
姿君 25
毛毛 10

字典與串列的差異

  • 串列(list):索引index => 值value
  • 字典(dict):鍵值key => 值value

如何把串列(list)變成字典(dict)

In [39]:
#寫法一
l = [["姿君",25],["Mars",20],["毛毛",10]]  #list
my_dict = {}  ##空字典
for item in l:
    name = item[0]
    score = item[1]
    my_dict[name]=score      # 設定值:字典名稱[key]=value
    print("拿取值",my_dict[name])  # 拿取值:字典名稱[key] 
print(my_dict)
拿取值 25
拿取值 20
拿取值 10
{'姿君': 25, 'Mars': 20, '毛毛': 10}
In [40]:
#寫法二
l = [["姿君",25],["Mars",20],["毛毛",10]]
my_dict = {}  ##空字典
for name,score in l:
    my_dict[name]=score      # 設定值:字典名稱[key]=value
print(my_dict)
{'姿君': 25, 'Mars': 20, '毛毛': 10}

函式 Function

  • 參數(patameter)是定義函式時指定的名稱,可有可無
  • 引數(argumwnt)是函數呼叫時傳入的真正物件,在呼叫時會建立參數和引數的綁定關係。
    • 需和參數的個數一樣
  • 函式內的程式碼可以有各種可能(eg. 迴圈、判斷式、運算...)
  • return 回傳,可有可無(若無會回傳None),用tuple可回傳多個物件

函式 語法:

使用關鍵字 def 宣告。

In [ ]:
#定義函式
def 函式名稱(參數1,參數2,...):
    程式碼
    程式碼
    程式碼
    return 物件1,物件2,物件3


#呼叫函式
函式名稱(引數1,引數2,...)
  • 自己打造工具
  • 利用呼叫,方便重複利用
    • 程式碼更為簡潔

def 洗衣機(): 注水 旋轉清洗 排水 旋轉脫水

title

到咖啡機弄一杯咖啡

  • 打開開關
  • 放下杯子
  • 選擇「咖啡類別」,按下製作
  • 咖啡機「製作咖啡」
  • 得到一杯咖啡 title title

Recall

還記得我們使用過不少工具:print()、ord()、max()...,
這些都是內建函式Bult-in Function,他們背後的運作原理可能像是這樣:

In [3]:
print(max([1,2,7,9,10]))
a=max([1,2,7,9,10])
print(a)
10
10
In [4]:
def my_max(data):
    num_max = -999999999
    for i in data:
        if i>=num_max:
            num_max = i
    return num_max
print(my_max([1,2,7,9,10]))
10

練習 - 自己寫一個 Function

判斷是否為閏年:
從西元元年起,每隔4年為閏年,但逢百年不算在內,唯一的例外是400年或400年的倍數,仍舊為閏年。不為閏年的即為平年。

  • 西元年可被4整除,但不能被100整除
  • 西元年份除以400可整除

答案:

  • 閏年:2000、2400
  • 平年:1800、1900、2100、2200、2300、2500

Hint:

  • 判斷式:if、elif、else
  • a%b:可以取a除以b的餘數
In [ ]:
def is_leap(year):
    leap = False
    ...
    你的程式碼
    ...
    return leap

print(is_leap(2000))
print(is_leap(1800))

答案

In [6]:
def is_leap(year):
    leap = False
    if year%4==0 and year%100!=0:
        leap = True
    elif year%400==0:
        leap = True
    return leap

print(is_leap(2000))
print(is_leap(1800))
True
False