3.資料型態:進階主題#

資料型別的可變與不可變#

之前講到在python中所有資料都是物件,而變數是物件的標籤。(請參考:[0.資料型態:bool, int, float, str]。)

我們將資料賦值到一個變數的這個過程就叫做實例化(initialization)。 例如:

pi = 3.1415926

我們把一個float物件實例化為pi這個變數,並把3.1415926賦值給該變數。 而所謂資料型態的可變或不可變,就是指當資料實例化後,它的值能不能夠被改變。

資料型態與是否可變

type

example

immutable

bool

True, False

immutable

int

42, 19, 112

immutable

float

3.14, 0.13

immutable

str

‘Hi’, “Hello”, ‘’’Bye!’’’, “””Bye!”””

immutable

list

[‘a’, ‘b’, ‘c’, ‘d’, ‘a’]

mutable

tuple

(‘a’, ‘b’)

immutable

dict

{‘a’: 1, ‘b’: 2}

mutable

set

{‘a’, ‘b’, ‘c’}

mutable

可變的資料型態

a_list = [1, 2, 3]
a_list[0] = 'a'

print(a_list)
['a', 2, 3]

不可變的資料型態

a_tuple = (1, 2, 3)

a_tuple[0] = 'a' # tuple為不可變的資料型態
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[2], line 3
      1 a_tuple = (1, 2, 3)
----> 3 a_tuple[0] = 'a' # tuple為不可變的資料型態

TypeError: 'tuple' object does not support item assignment

知道資料型態可不可變,so what? 事實上這決定了一些程式的行為。

請先看以下這段code:

x = [1, 2, 3]

y = x

x[0] = 'a'

我們知道list是可變的,請猜猜看print(y)的話會輸出什麼? 答案是:

print(y)
['a', 2, 3]

發現到雖然我們改變的是x,但y的內容也一併被改變了!

這是因為x和y都僅僅是一個list物件的標籤而已, x和y都指向一開始值為[1,2,3]的list物件, 而list是可變的, 所以當我們改變list的內容時, 另一個貼著這個list的標籤y也就被影響了。

# x 和 y 指向同一個物件。

print(id(x))
print(id(y))
4380504384
4380504384

最後,list是可變的,而tuple是不可變的,

這也是為什麼對list做以下操作是合法的,對tuple卻不行。

a_list = [1, 2, 3]

# indexing後賦值
a_list[0] ='a'
a_list.append('d')

日期與時間#

python內建的時間與日期處理,需要引入一個datetime”模組”。 所謂模組可以想像是一個函式庫,讓我們可以快速取用各種工具,就不用「自己造輪子了」。

要取用函式庫需要先做引入(import)的動作:

from datetime import datetime

以下語法會產生出一個datetime物件指出現在的時間,該物件儲存了年月日時分秒與毫秒。

today = datetime.now()

type(today)
print(today)
2024-03-28 07:30:22.086995

datetime物件的相關操作方法:

print(today.year)
print(today.month)
print(today.day)
print(today.hour)
print(today.minute)
print(today.second)
print(today.weekday())
2024
3
28
7
30
22
3

其他建立datetime物件的方法:

birthday = datetime(2022, 11, 30)
print(birthday)
2022-11-30 00:00:00

日期的運算需要利用datetime模組中另一個物件timedelta:

from datetime import datetime, timedelta

sign_on_dt = datetime(2024, 2, 1)

save_dt = sign_on_dt  + timedelta(days=180)

print(save_dt)
2024-07-30 00:00:00

文字轉日期#

常用的操作是把文字字串轉成日期型態再去做運算

today = '20231212'
the_big_day = '20200520'

today_dt = datetime.strptime(today, '%Y%m%d')
the_big_day_dt = datetime.strptime(the_big_day , '%Y%m%d')

days_together = today_dt - the_big_day_dt

type(days_together)
print(days_together.days)
1301

日期轉文字#

today = datetime.now()

print(today.strftime('%Y%m%d'))
20240328

格式列表#

format

描述

例子

%y

補零后,以十進制數表示的,不帶世纪的年份。

00, 01, …, 99

%Y

十進制數表示的帶世纪的年份。

0001, 0002, …, 2013, 2014, …, 9998, 9999

%m

以零填充的並以十進位數字表示的月份。

01, 02, …, 12

%d

補零后,以十進制數顯示的月份中的一天。

01, 02, …, 31

%H

以補零后的十進制数表示的小時(24 小時制)。

00, 01, …, 23

%I

以補零后的十進制數表示的小時(12 小時制)。

01, 02, …, 12

%M

補零后,以十進制數顯示的分鐘。

00, 01, …, 59

%S

補零后,以十進制數顯示的秒。

00, 01, …, 59

%w

以十進制數顯示的工作日,其中0表示星期日,6表示星期六。

0, 1, …, 6

%W

以補零后的十進制數表示的一年中的週序號(星期一作為每週的第一天)。 在新的一年中第一個星期一之前的所有日子都被視為是在第 0 週。

00, 01, …, 53