Try   HackMD

2. 型態與運算子


2.1 基本資料型態

Python基本資料型態(或稱為內建型態)有:

  • 數值型態(Numeric type) - int, float, bool, complex
  • 字串型態(String type)- str
  • 容器型態(Container type) - list, set, dict, tuple

Python 3後,整數型態一率為int,不再區分整數(int)與長整數(long),而且整數的長度沒有限制。

2.1.1 數值型態

整數型態 - int

Python 3後,整數型態一率為int,不再區分整數(int)與長整數(long),而且整數的長度沒有限制。

  • 十進位整數:預設的整數位數,例如:9、89、135等等。
  • 二進位整數:在數字前加上0b或0B,後面接上0~1的數字,例如:0b0001、0B10011100。
  • 八進位整數:在數字前加上0o或0O,後面接上1~7的數字,例如:0o6、0O163。
  • 十六進位整數:在數字前加上0x或0X,後面接上19以及AF的數字,例如:0x1A、0X8C60。

從Python 3.6開始,數字可以加上底線,這對很長的整數閱讀上,會很有幫助。
例如:

1_000_000_000
0x12_34_56_78
0b1000_1101_0101
print()函示

為了可以輸出結果到終端機視窗,可以使用print()函示,如果有多個結果同時輸出,可以使用逗號,分隔。

例如:

print(234)
print('Hello!', 456)  # 同時有多個結果要一次輸出

會輸出:

234
Hello! 456

如果想要輸出多的字串時,每個字串用逗號「,」做分隔,可以加上sep=', ',例如:

print('Hello!', '456', sep=', ')

會輸出:

Hello!, 456

print()函式預設輸出後一定會做換行,如果不想換行,可以指定end='',例如:

print("Hello, ", end='')
print("World!")

會輸出:

Hello, World!
type()函式

無論是十進位、二進位、八進位、十六進位整數,都是int類別,如果想知道某種資料的型態,可以使用type()函式來取得,並搭配print()函式來顯示到終端機視窗上。
例如:

print(type(10))
print(type(0b1001))
print(type(0o123))
print(type(0x9C))

終端機視窗會看到這樣的結果:

<class 'int'>
<class 'int'>
<class 'int'>
<class 'int'>
浮點數

浮點數是float型態,也就是帶有小數點得的數字。
例如:

3.14159
6.0
複數

複數的形式為a + bj,型態為complex,複數可以直接做運算。
例如:

print(3 + 2j + 5 + 6j)
print(type(5j))

會輸出:

8 + 8j
<class 'complex'>

2.1.2 布林型態

布林型態的值只有TrueFalse兩種,為bool型態,True代表的是「真」,而False代表的是「假」。

使用type()函式:

print(type(True))
print(type(False))

會輸出:

<class 'bool'>
<class 'bool'>

請注意TrueFalse兩個單字的第一個字母都必須為大寫,不可為小寫。

2.1.3 字串型態

Python中要表示字串,可以使用一對單引號' '或一對雙引號" "來包圍要表示的文字。

例如:

'Hello, World!'
'+886-1234567'

單引號和雙引號的功用一樣,可以視情況做互換,例如字串本身包含有單引號時,就可以用雙引號來包圍字串。

例如:

"I'm a good student"
'Here is my "STUFF"!!'

字串裡定義了一些特殊的轉義文字,有特殊功用或意義,不會直接在畫面上輸出。

符號 說明
\\ 反斜線\
\' 單引號''
\" 雙引號"
\ooo 以8進位字元碼顯示字元,最多三位數,例如:`\101'
\xhh 以8位元16進位字元馬顯示指定字元,例如:\xE8
\uhhhh 以16位元16進位字元馬顯示指定字元,例如:\u32E8
\Uhhhhhhhh 以32位元16進位字元馬顯示指定字元,例如:\U000032E8
\0 空字元,而不是空字串,等同於\x00
\n 換行
\r 歸位(同一行)
\t TAB
'Hi,\nGood Morning'
"1\t2\t3"

如果字串內想要顯示像\t這樣的字串的話,必須寫成\\t或是可以在字串前面加上r代表直接使用原始字串而不需要轉義,例如:

print('\\t')
print(r'\t')

輸出為:

\t
\t

在使用單引' '號或雙引號" "表示字串時,程式碼不可以換行,如果字串內容必須換行,可以使用\n或三重引號,在三重引號內輸入的任何內容和格式都會被如實保留,例如:換行、縮排等等。

print('''This is Aaron's book,
May I talk to Amber.
Good morning~!```)

輸出為:

This is Aaron's book,
May I talk to Amber,
Good morning~!

Python本身不支援多行註解,但是因為三重引號內可以被輸入任何內容,因此如果有暫時不想執行的程式碼都可以用三重引號來包圍,變相作為多行註解使用。

練習

下面數字是什麼型態?

0xf
0.0
0o8
'4.4'
3.1e-1
999
0a
0b110

2.1.4 型態轉換

int()

如果想將字串、浮點數、布林等型態轉換成整數,可以使用int()函式來作轉換。

整數形態和字串型態無法直接做運算,就必須經過轉換。
例如:

print(3 + int('9'))
print(int('88') + 12)

輸出:

12
100
bin()、oct()、hex()`

如果想直接輸出八進位、十六進位整數到畫面上,可以這樣做:

print(bin(10))
print(oct(10))
print(hex(10))

會輸出:

0b1010
0o12
0xa

其輸出的資料型態皆為字串,例如使用type()函式來得到其資料型態:

print(type(oct(10)))
print(type(hex(10)))

會輸出:

<class 'str'>
<class 'str'>

當我們使用int()函式從字串建立整數時,可以指定其基底為2進位、8進位或16進位。

例如:

print(int('10', 2))
print(int('10', 8))
print(int('10', 16))

會輸出:

2
8
16

需注意,如果要將'3.14'這樣的字串透過int()取得整數部分會出現ValueError錯誤,必須先使用float()轉為福點數後再用int()取得整數部分。

float()

可以將字串轉為浮點數型態。

bool()

bool()內可以傳入任何型態,只要傳入的是:None、False、0、0.0、0j(複數)、''(空字串)等等,都會回傳False,這些型態以外的的其他值傳入bool(),都會回傳True

str()

可以將數值形態的資料轉換成字串型態。

ord()

顯示某個字元的編碼,例如:

ord('哈') #輸出:21704
chr()

將文字編碼轉為文字顯示,例如:

chr(21704) # 輸出:'哈'
練習

ㄧ、下面有一程式,使用者輸入兩個數字,加總後顯示到標準輸出上:

print('請輸入數字1')
a = input() # 程式會停在這裡等待使用者輸入
print('請輸入數字2')
b = input() # 程式會停在這裡等待使用者輸入
print('總和是: ' + a + b)

此程式執行結果為:

請輸入數字1:
3
請輸入數字2:
5
總和是: 35

正確執行結果應該為:

請輸入數字1:
3
請輸入數字2:
5
總和是: 8

請問該怎麼修改程式碼?

請使用轉型函式來解決問題
二、下面有一程式,使用者輸入一個帶有小數點的數字,保留小數點兩位後輸出到標準輸出:

print('請輸入一個小數數字: ')
a = input()
print('保留小數兩位數: ' + a)

請問該怎麼修改程式碼?

請使用型態轉換來解答問題

2.2 群集型態

在開發過程當中,常常會需要收集一些資料後一起做處理,這些資料根據用途不同可能會使用不同的資料結構來做收集,例如可能會需要資料依照順序排列、需要資料不重複、需要每筆資料都有對應的的鍵值(key value)來做存取等等,相比其他程式語言需要使用特定的函式或類別來做建立,Python提供了語法上的直接支援,因此使用起來會更容易且方便。

2.2.1 清單(list)

清單的型態是list,其特色為:

  • 有序(sorted)
  • 索引(index)
  • 內容可變
  • 長度可變

清單可以使用[ ]來建立,裡面每個元素使用逗號「,」做區隔。

可以透過索引來取得指定元素值,起始為0,代表第一個元素,如:a[0]代表a的第一個元素值。

例如:

[1, 2, 3]
['Aaron', 'Apple', 'Amber', 'Astrid']
[3.4, True] # list內的元素可以是相異的資料型態
[] # 建立長度為0的清單
print([1, 2, 3])
print([1, 2, 3][0])
print([1, 'Aaron', True, 3.3, 'Today'])
print([1, 'Aaron', True, 3.3, 'Today'][4])

會輸出:

[1, 2, 3]
1
[1, 'Aaron', True, 3.3, 'Today']
Today

清單方法:

方法名稱 說明
append() 新增一筆資料到清單的最後面
remove() 移除清單內某個元素值
reverse() 將清單內元素順序反過來
sort() 排序清單
extend() 新增多筆資料到清單

例如:

a = [1, 2, 3,] # 最後一個逗號可以省略,如: [1, 2, 3]
a.append(999)
a.append(999)
a.append(999)
a.append('abc')
a.append(False)
print(a)
print(a[4])
a[4] = 'xxx'
print(a)
a.remove(999)
a.remove('abc')
a.reverse()
a = [3, 2, 6,0, 1, 9]
a.sort()
a.extend('abcde')
print(len(a))
a.append(0)
print(len(a))
print(a)

會輸出:

[1, 2, 3, 999, 999, 999, 'abc', False]
999
[1, 2, 3, 999, 'xxx', 999, 'abc', False]
11
12
[0, 1, 2, 3, 6, 9, 'a', 'b', 'c', 'd', 'e', 0]
nums = [1, 2, 3]
print(nums)
nums.append(4)
print(nums)
print(nums[0])
nums[3] = 0
print(nums)
nums.remove(0)
print(nums)

輸出為:

[1, 2, 3]
[1, 2, 3, 4]
1
[1, 2, 3, 0]
[1, 2, 3]
群集型態通用方法

通用方法可以使用在Python支援的各種群集型態上:

方法名稱 說明
len() 取回該群基資料的長度(共有幾筆資料)
del 刪除指定索引位置的元素
in 判斷資料是否存在於該群集資料中

remove()方法和del都是刪除元素,但是remove()是根據給定的元素值來做判斷,而del是給定指定的位置,容易混淆,還請多加注意。

範例:

nums = [1, 2, 3]
del nums[0]
print(nums)
print(len(nums))
print(4 in nums)

輸出為:

[2, 3]
2
False

另外,你也可以使用list()方法來將其它群集資料轉成list()型態。

print(list('abcdef'))

會輸出:

[a, b, c, d, e, f]

可以使用list()函式來轉換成清單型態的資料必須是可迭代(iterable)的物件,像是字串、集合(set)或Tuple(tuple)等等,關於可迭代的的含義,之後的的章節會另外說明。

練習

請將:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

透過清單的操作,變成:

[8, 6, 4, 2, 0, 'ok']

並輸出到終端畫面上。

2.2.2 集合(set)

集合這個群集資料結構裡面的內容沒有順序且元素不會重複,可以使用{ }來建立集合,建立時每個元素以逗號「,」分開來,如果建立的時候有重複的元素,則只會保留一個,重複的都會被去除,例如:

print({'A', 'B', 'C'})
my_set = {1, 2, 3, 1, 2, 3}
print(my_set)

會輸出:

{'A', 'B', 'C'}
{1, 2}

如果要建立空的集合,並不是使用{},這會建立一個空的字典(dict),而是要呼叫set()函式,例如:

my_set = set()

集合的方法:

方法名稱 說明
add() 新增一個元素
remove() 刪除元素

而上一小節提到的通用方法len()、in也可以用在集合上面,例如:

my_set = {1, 2, 3}
my_set.add(4)
my_set.add(3)
print(my_set)
my_set.remove(3)
print(my_set)
print(len(my_set))
print(3 in my_set)

會輸出:

{1, 2, 3, 4}
{1, 2, 4}
3
False

由於集合必須保證內容的不重複,所以並非所有資料型態的元素都可以放進去,例如:清單和集合就都不行。

{[1, 2, 3]}
{{1, 2, 3}}

會輸出:

TypeError: unhashable type: 'list'
TypeError: unhashable type: 'set'

要從清單、字串或Tuple建立集合,也可以使用set()函式,例如:

print(set('ABCDE'))
print(set([1, 2, 3])
print(set((1, 2, 3)))

會輸出:

{'A', 'B', 'C', 'D', 'E'}
{1, 2, 3}
{1, 2, 3}

其他範例:

a = {0, 1, 2, 3, 1, 2, 3, 4, 5, 3, 4}
a = set()
print(a)
print(type(a))
a.add('A')
a.add('A')
a.add(True)
a.add(44)
a.remove(44)
print(a)
print(len(a))
a = [1, 2, 3]
a.append({'A', 'B'})
print(a[3])

會輸出:

set()
<class 'set'>
{True, 'A'}
2
{'A', 'B'}

清單跟集合可以互相轉換:

a = list({0, 1, 2})
print(a)
a = set([0, 1, 2])
print(a)
a = set('abc')
print(a)

會輸出:

[0, 1, 2]
{0, 1, 2}
{'a', 'c', 'b'}
練習

請依序寫出下面需求的程式碼,執行後顯示第八項的結果到終端畫面上:

  1. 建立一個清單,裡面有5個元素1, 2, 3, 4, 5,並指定給a變數。
  2. 將清單第一個元素修改為0
  3. 將清單最後一個元素修改為0
  4. 將0從清單裡去除
  5. 將清單由大到小排序
  6. 將清單專換成集合
  7. 加入2和3兩個數字到集合
  8. 集合內現在有幾個元素?

2.2.3 字典(dict)

字典用來儲存兩兩對應鍵(key)與值(value),型態為dict,建立時可以使用{ }以及冒號「:」,鍵在左,值在右的格式,例如:

phones = {'Aaron': '+886-1234567', 'Amber': '+886-7654321'}
print(phones['Aaron'])

上面範例會建立兩筆dict資料,'Aaron'和'Amber'為鍵,'+886-1234567'和'+886-7654321'為各自的值;透過鍵來取得值,該範例會輸出:

+886-1234567

注意:

  1. 鍵不可以重複。
  2. 透過[]來取得鍵所對應的值。
  3. del可以刪除某個鍵與值。
  4. in可以判斷該鍵是否存在。

如果透過[]取出值時該鍵不存在,會發生KeyError的錯誤,可以使用in先判斷該鍵是否存在,例如:

data = {'A': 123, 'B': 456, 'C': 789}
print(data)
del data['B']
print(data)
print('B' in data)

會輸出:

{'A': 123, 'B': 456, 'C': 789}
{'A': 123, 'C': 789}
False

字典的方法:

方法名稱 說明
get() 取得指定鍵的值
items() 取得每一對鍵值,會回傳dict_items
keys() 取得所有的鍵,會回傳dict_keys
values() 取得所有的值,會回傳dict_values
data = {'A': 123, 'B': 456, 'C': 789}
print(data.items())
print(data.keys())
print(data.values())

會輸出:

dict_items([('A', 123), ('B', 456), ('C', 789)])
dict_keys(['A', 'B', 'C'])
dict_values([123, 456, 789])

除了使用{}建立字典外,也可以使用dict()fromkeys()函式來建立字典,例如:

data = dict(A = 123, B = 456, C = 789) 
# 等同於data = {'A': 123, 'B': 456, 'C': 789}
data2 = data.fromkeys(['A', 'B'], '000')
print(data)
print(data2)

會輸出:

{'A': 123, 'B': 456, 'C': 789}
{'A': 000, 'B': 000}

透過dict()方法建立字典,鍵不需要用大括號包圍,且不能給重複的鍵。

練習
a = {'A': 1, 'B': 2, 'C': 3}
  1. 將鍵為'B'的值改為5
  2. 將鍵為'C'的值轉型成字串
  3. 刪除鍵為'A'的該筆資料
  4. 新增鍵'D',設定其值為99
  5. 新增鍵'E',設定其值為一清單,該清單內有2和3兩個值
  6. 計算a這個字典目前有幾組元素
  7. 取出a字典內所有的值,用清單存放,並設定給b變數

答案:

a['B'] = 5
print(a)
a['C'] = str(a['C'])
print(a)
del a['A']
print(a)
a['D'] = 99
print(a)
a['E'] = [2, 3]
print(a)
print(len(a))
b = list(a.values())
print(b)

2.2.4 Tuple(tuple)

Tuple很多地方跟list類似,如:有順序性、可以使用[]來存取元素,但是Tuple在建立後就不可以修改內容,建立Tuple有兩個直接支援的語法:直接在某個值後面加上「逗號,」或是使用一對小括號(),例如:

a = 10,
print(a)
b = 10, 20, 30
print(b)
c = 'Aaron', 10, True
print(c)
d = (100, 101, 102)
print(d)
print(d[0])
type(d)

會輸出:

(10, )
(10, 20, 30)
('Aaron', 10, True)
(100, 101, 102)
100
<class 'tuple'>
  1. 雖然用逗號就可以建立Tuple,但是用小括號的話更可以讓人容易一眼就看出其型態。

  2. 建立只有一個元素的Tuple不可以使用小括號,而要使用逗號,例如: (elem)不行,elem, 可以。

  3. 事實上,之前在建立list、set、dict時也都是省略了最後一個逗號,所以如果之後有看到逗號,就不用太訝異。

Tuple內的元素可以做拆解(Unpack)指定給不同的變數,例如:

a, b, c = (10, 20, 30)
print(a)
print(b)
print(c)

會輸出:

10
20
30

因為Tuple的括號是可以省略的,所以有可能會看到下面這樣的寫法:

a, b, c = 10, 20, 30
a, b = b, a
print(a)
print(b)

會輸出:

20
10

拆解元素的特性同樣可以用在list、set上面,例如:x, y, z = [1, 2, 3]x, y, z = {1, 2, 3}

除了拆解(Unpack)元素之外,還有個進階拆解元素功能(Extended Iterable Unpacking),例如:

a, *b = (1, 2, 3, 4, 5)
print(a)
print(b)
a, *b, c = [1, 2, 3, 4, 5]
print(a)
print(b)
print(c)

會顯示:

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

在某個變數上指定*後,其他變數會被分配單一值,剩下的元素會以list的型態指定給標上星號的變數。

a = (1, 2, 3)
# b = a[0]
# c = a[1]
# d = a[2]
b, c, d = a # 等同上面三行
print(b, c, d)

b, c, d = [4, 5, 6]
print(b, c, d)

b, c, d = {7, 8, 9}
print(b, c, d)

b, c, *d = 1, 2, 3, 4, 5, 6
print(b, c, d)

b, *c, d = 1, 2, 3, 4, 5, 6
print(b, c, d)

會輸出:

1 2 3
4 5 6
8 9 7
1 2 [3, 4, 5, 6]
1 [2, 3, 4, 5] 6

2.3 變數與運算子

2.3.1 變數

在寫程式時,我們會經過很多運算來得到結果,香蕉每斤20元,想要得到10斤、20斤、30斤要多少錢,例如:

print('香蕉10斤價格:', 20 * 10)
print('香蕉20斤價格:', 20 * 20)
print('香蕉30斤價格:', 20 * 30)

一週後香蕉每斤價格變動了,必須每一行修改程式碼,如果說程式裡有10個地方都需要計算香蕉的價格,那就必須修改10個地方,如果漏掉一個地方,程式的執行結果就會出現錯誤。是不是有個更方便的辦法可以更快的修改並且降低錯誤呢?答案就是使用「變數」,請看下面程式碼:

banna_price = 20
print('香蕉10斤價格:', banna_price * 10)
print('香蕉20斤價格:', banna_price * 20)
print('香蕉30斤價格:', banna_price * 30)

這裡的執行結果會和上一次的程式碼一樣,但是,未來香蕉每斤價格改變了,只需要修改banna_price後面的數字,不管有多少行,因為全部都會使用banna_price內存放的20來做計算,所以都會跟著反映在執行結果上,減少了修改可能造成的錯誤,並且幫20取了一個有意義的名字,而非不明意義的魔術數字。

banna_price被稱為變數(variable),透過等號「=」號,我們將20存到變數裡面,這個變數的值就相當於20,之後,就可以直接拿變數來做運算。

Python屬於動態型別語言,變數本身沒有型態,且可以不需要經過宣告,在第一次透過「=」號指定值的時候就是建立了一個變數,如果在建立之前,嘗試存取變數,會出現NameError的錯誤,例如:

print(x)

會輸出:

NameError: name 'x' is not defined
id()

Python內,變數始終都會是參考(reference),透過等號只是把參考指定給變數,可以呼叫id()函式來取得變數的記憶體位址,例如:

x = 10
y = x
print(id(x))
print(id(y))

可能的輸出如下(因電腦不同,記憶體位址可能會與這裡的輸出不同,但兩個變數的記憶體位置會一樣):

289012347
289012347

一開始x參考到了10這個整數物件,也就是x裡存放的是10的物件參考,接著把x內存放的參考也放到y變數內,所以y變數也參考到10物件,也就是同一個物件。

在看下面範例:

x = 1
print(id(x))
x = x + 1
print(id(x))

會輸出:

18090383000
18094327699

一開始x參考到1這個物件,接著x參考的內容加上1之後會產生一個新的物件,然後透過等號將新的物件參考在指定給xx內舊的參考會被覆蓋成新的參考。

在看下面範例:

x = [1, 2, 3]
print(x)
y = x
y[0] = 0
print(x)

輸出:

[1, 2, 3]
[0 ,2, 3]

在指定y = x的時候,兩個變數因為參考到同一個物件,所以將y[0]改為0後,原本的x內的元素0也跟著改變了。

is、is not

除了使用id()函式來觀察變數參考的記憶體之外,還可以使用is指令來確認兩個變數是否參考到同一物件,用is not來判兩個變數參考是否不一樣。

x = 3
y = x
print(x is y)
y = 20
print(x is y)

會輸出:

True
False

變數本身沒有型態,可以對著同一個變數指定不同形態的值,當呼叫變數的某個方法的時候,只要確定方法存在就不會出現錯誤,例如listtuple兩種型態都有查詢元素位置的index()方法,因此下面的程式碼不會出錯:

x = [1, 2, 3]
print(x.index(2))
x = (1, 2, 3)
print(x.index(2))

當不再需要某個變數,可以呼叫del來刪除它,例如:

x = 10
del x
print(x)

會輸出:

NameError: name 'x' is not defined

會出現錯誤,因為x變數已經被刪掉了。

2.3.2 算數運算子

算術運算子有:

運算子 說明
加法運算
減法運算
乘法運算
** 指數運算
除法運算
// 除法運算,但只保留整數
除法運算,但是只取餘數
數值的運算
print(1 + 2)
print(1 - 2)
print(1 * 2)
print(2 ** 3)
print(1 / 2)
print(1 // 2)
print(1 % 2)

會輸出:

3
-1
2
8
0.5
0
1

需注意小數點的運算可能會出乎意料:

print(0.1 + 0.1 + 0.1)
print(1.0 - 0.8)
print(0.1 + 0.1 + 0.1 == 0.3)

會輸出:

0.30000000000000004
0.19999999999999996
False

這並不是Python程式語言的錯誤,而是Python遵守IEEE 754浮點運算標準,而這個運算標準因為使用分數和指數來表示,所以會有浮點數誤差。

如果對小數運算的精度要求很高的話,可以使用decimal.Decimal類別來做運算,例如:

import decimal
d1 = decimal.Decimal('0.1')
d2 = decimal.Decimal('0.1')
d3 = decimal.Decimal('0.1')
print(d1 + d2 + d3)

在指定數字的時候,必須使用字串,但可以直接使用算術運算子做運算

如果對著布林值做運算,True會被當作1,False會被當作0,然後再進行運算,例如:

print(True+False)

會輸出:

1
字串的運算

使用「+」可以用來串接運算,使用「*」可以重複字串,例如:

t1 = 'Hello'
t2 = 'Aaron'
print(t1 + t2)
print(t1 * 5)

會輸出:

HelloAaron
HelloHelloHelloHelloHello

字串因為本身不可以被修改,所以每次運算後都是產生新的字串。

Python本身偏向強型別,也就是不同型態之間在做運算時,比較不會進行自動轉換,所以字串和數字不能進行+運算,如果要進行串接,就必須先把數字轉成字串,如果要進行算數相加,就必須將字串先轉成數字,例如:

print('10' + str(3))
print(10 + int('3'))

會輸出:

103
13
list、tuple運算

list使用「+」運算子可以進行串接,使用「*」,例如:

n1 = ['one', 'two']
n2 = ['three', 'four']
print(n1 + n2)
print(n1 * 2)

會輸出:

['one', 'two', 'three', 'four']
['one', 'two', 'one', 'two']

「+」和「*」運算在tuple上也有相同的效果,雖然tuple本身不能變動,但是當中的元素是可以變動的,例如:

n1 = [1, 2]
n2 = [3, 4]
nn = (n1, n2)
print(nn)
n1 = 5, 6
print(nn)

會輸出:

([1, 2], [3, 4])
([5, 6], [3, 4])
練習
  1. 將:
a = [3, 4]
b = [5, 6]

轉換成:

[3, 4, 5, 6, 3, 4, 5, 6]

並存放到result變數裡

  1. 將:
c = [3.3, 6.6, 9.9]

轉換成:

[9, 6, 3]

並存放到result變數裡

2.3.3 比較運算子

比較運算子 說明
> 大於
>= 大於或等於
< 小於
<= 小於或等於
== 等於
!= 不等於
<> 不等於(與!=功能相同)Python 3已不支援

<>效果與!=相同,其只是為了相容性而存在,這裡列出只是為了將來見到不至於迷惘,請盡量使用!=來判斷,而不要使用<>

比較的結果,不是Ture就是False,代表成立或不成立。

請勿將==!=isis not搞混,前者是比較物件真實的值,而後者是比較兩個物件的參考是否相同

x = [2, 3]
y = [2, 3]
print(x == y)
print(x is y)

會輸出:

True
False

除了數字之外,字串、listset、'tuple'和dict也都可以進行比較運算,其運算依從第一個元素依照順序做比較,而字元的比較為比較其字元碼(如英文字為ASCII碼),例如:

print('AAC' < 'ABC')
print([2, 3] > [4, 5])
print((2, 3) == (4, 5))
print({2, 3} > {4, 5})
print({'A': 3} == {'A': 3)

會輸出:

True
False
False
False
True

2.3.4 指派運算子

除了目前已經用過的「=」指派運算子之外,其它的如下:

指派運算子 範例 等同於
+= a += b a = a + b
-+ a -= b a = a - b
*= a *= b a = a * b
/= a /= b a = a / b
//= a //= b a = a // b
%= a %= b a = a % b
&= a &= b a = a & b
|= a |= b a = a | b
^= a ^= b a = a ^ b
<<= a <<= b a = a << b
>>= a >>= b a = a >> b

2.3.5 邏輯運算子

邏輯運算子 說明
and 且,左右運算元都必須為真,其結果才為真,否則為假
or 或,左右兩邊只要有一運算元為真,其結果即為真
not 反相
print(True and True)
print(True and False)
print(True or False)
print(not True)

會輸出:

True
False
True
False

None、False、0、0.0、0j、''、()、[]、{}等傳入bool()都會是False,其它值都會是True,這個原理也同樣套用在邏輯運算子上。

Python的邏輯運算子有捷徑運算的特性,也就是其運算的判斷由左至右,只要結果確立了,就會回傳確定結果位置的值。

and運算子左運算元如果為假,就可以確認邏輯不成立,因此可以不用繼續運算右運算元;or左運算元為真,則可以確定邏輯成立,因此可以不用運算右運算元,當判斷停留在哪裡,就會回傳該位置的運算元為結果值,例如:

print([] and 'Aaron')
print([1, 2] and 'Aaron')
print([] or 'Aaron')
print([1, 2] or 'Aaron')

會輸出:

[]
Aaron
Aaron
[1, 2]

2.3.6 位元運算子

位元運算子 說明
& AND運算
| OR運算
^ 互斥OR運算
~ 補數運算
>> 右移運算(左邊原來是0則補0,是1就補1)
<< 左移運算(右邊會補上0)

位元運算即是逐個位元做運算,例如:

print(0b10010001 & 0b01000001)
print(0b10010001 | 0b01000001)
print(~0b11)
print(1 << 1) # 等同於2的1次方
print(1 << 3) # 等同於2的3次方

會輸出:

1
209
-4
2
8

邏輯運算子除了數值的運算之外,還可以用在set上做交集(&)、聯集(|)、互斥(^)以及減集(-),並且可以用比較運算子(`>、<、>=、<=、==)來比較兩個`set`的包括關係。

2.3.7 索引切片運算

在Python中,只要具有索引特性的型態,基本上都可以使用切片(slice)運算,像是字串、list、tuple等等,透過切片運算,可以取得其內容之中的某一個片段,例如:

name = 'Aaron'
print(name[0:3])
print(name[3:])
print(name[:2])
print(name[:])
print(name[:-1])
print(name[-3:-1])

print(3 and 4)
print(0 and 'Aaron')
print([] or 'OK')
print('OK' or [])
print(not 'OK')
print(not 0)

print(False and 'A')
print({} or '9')
print(not 0j)
print('abc' and ())
print(99 or 88)
print([3, 4, 5] and (3, 2))
print(6 and 9 or 3)

輸出為:

Aar
on
Aa
Aaron
Aaro
ro

4
0
OK
OK
False
True
False
9
True
()
99
(3, 2)
9

重點如下:

  1. 其索引格式為:[start, end],start會包含其指定的索引值,但end指定的索引值不包含,索引從0開始代表第一個元素。
  2. 如果是負數,表示從後面數,-1代表倒數第一個元素。
  3. 如果冒號前面沒有指定,表示從頭開始,如果冒號後面沒有指定,表示最後一個元素。

切片運算另一個形式是:[start:end:step],step代表每次間隔的內容,例如:

data = '1234567890'
print(data[::2])
print(data[::-1])

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]  # list

print(a[3:7])
print(a[3:])
print(a[:-1])
print(a[-3:])
print(a[::2])
print(a[::2])
print(a[1::2])
print(a[2::3])
print([a[0], a[-1]])
print(a[5::-2])

會輸出:

13579
0987654321

[4, 5, 6, 7]
[4, 5, 6, 7, 8, 9, 0]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[8, 9, 0]
[1, 3, 5, 7, 9]
[1, 3, 5, 7, 9]
[2, 4, 6, 8, 0]
[3, 6, 9]
[1, 0]
[6, 4, 2]

負數偏移表示以負偏移1的方式來取字串,結果就會變成反轉字串。