2020最新Python入門筆記

来源:https://www.cnblogs.com/chengxuyuanaa/archive/2020/04/19/12731846.html
-Advertisement-
Play Games

Python變數和數據類型 數據類型 print語句 註釋 Python的註釋以 # 開頭,後面的文字直到行尾都算註釋 # 這一行全部都是註釋... print 'hello' # 這也是註釋 這裡要註意註意:不管你是為了Python就業還是興趣愛好,記住:項目開發經驗永遠是核心,如果你沒有2020 ...


 

Python變數和數據類型

數據類型

print語句

註釋

Python的註釋以 # 開頭,後面的文字直到行尾都算註釋

# 這一行全部都是註釋...
print 'hello' # 這也是註釋

這裡要註意註意:不管你是為了Python就業還是興趣愛好,記住:項目開發經驗永遠是核心,如果你沒有2020最新python入門到高級實戰視頻教程,可以去小編的Python交流.裙 :七衣衣九七七巴而五(數字的諧音)轉換下可以找到了,裡面很多新python教程項目,還可以跟老司機交流討教!

什麼是變數

定義字元串

字元串可以用''或者""括起來表示。

如果字元串本身包含'怎麼辦?比如我們要表示字元串 I'm OK ,這時,可以用" "括起來表示:

"I'm OK"
類似的,如果字元串包含",我們就可以用' '括起來表示:

'Learn "Python" in imooc'
如果字元串既包含'又包含"怎麼辦?

這個時候,就需要對字元串的某些特殊字元進行“轉義”,Python字元串用\進行轉義。

要表示字元串 Bob said "I'm OK".
由於 ' 和 " 會引起歧義,因此,我們在它前面插入一個\表示這是一個普通字元,不代表字元串的起始,因此,這個字元串又可以表示為

'Bob said "I'm OK".'
註意:轉義字元 \ 不計入字元串的內容中。

常用的轉義字元還有:

\n 表示換行
\t 表示一個製表符
\ 表示 \ 字元本身

raw字元串與多行字元串

我們可以在字元串前面加個首碼 r ,表示這是一個 raw 字元串,裡面的字元就不需要轉義了。例如:

r'\(~_~)/ \(~_~)/'

但是r'...'表示法不能表示多行字元串,也不能表示包含'和 "的字元串(為什麼?)

如果要表示多行字元串,可以用'''...'''表示:

'''Line 1
Line 2
Line 3'''

上面這個字元串的表示方法和下麵的是完全一樣的:

'Line 1\nLine 2\nLine 3'

還可以在多行字元串前面添加 r ,把這個多行字元串也變成一個raw字元串:

r'''Python is created by "Guido".
It is free and easy to learn.
Let's start learn Python in imooc!'''

Unicode字元串

轉義:

u'中文\n日文\n韓文'
多行:

u'''第一行
第二行'''

raw+多行:

ur'''Python的Unicode字元串支持"中文",
"日文",
"韓文"等多種語言'''

整數和浮點數

布爾類型

List和Tuple類型

list

按照索引訪問list

倒序訪問list

添加新元素

第一個辦法是用 list 的 append() 方法,把新同學追加到 list 的末尾:

>>> L = ['Adam', 'Lisa', 'Bart']
>>> L.append('Paul')
>>> print L
['Adam', 'Lisa', 'Bart', 'Paul']
append()總是把新的元素添加到 list 的尾部。

方法二是用list的 insert()方法,它接受兩個參數,第一個參數是索引號,第二個參數是待添加的新元素:

>>> L = ['Adam', 'Lisa', 'Bart']
>>> L.insert(0, 'Paul')
>>> print L
['Paul', 'Adam', 'Lisa', 'Bart']

從list刪除元素

  • 最後一個元素,我們可以用list的pop()方法刪除:
     >>> L = ['Adam', 'Lisa', 'Bart', 'Paul']
    >>> L.pop()
    'Paul'
    >>> print L
    ['Adam', 'Lisa', 'Bart']

pop()方法總是刪掉list的最後一個元素,並且它還返回這個元素,所以我們執行 L.pop() 後,會列印出 'Paul'

如果Paul同學不是排在最後一個怎麼辦?比如Paul同學排在第三:

>>> L = ['Adam', 'Lisa', 'Paul', 'Bart']
要把Paul踢出list,我們就必須先定位Paul的位置。由於Paul的索引是2,因此,用 pop(2)把Paul刪掉:

替換元素

替換時直接賦值

tuple

tuple是另一種有序的列表,中文翻譯為“ 元組 ”。tuple 和 list 非常類似,但是,tuple一旦創建完畢,就不能修改了。

創建tuple和創建list唯一不同之處是用( )替代了[ ]。

tuple沒有 append()方法,也沒有insert()和pop()方法。

創建單元素tuple

包含 0 個元素的 tuple,也就是空tuple,直接用 ()表示:

>>> t = ()
>>> print t
()

創建包含1個元素的 tuple 呢?來試試:

>>> t = (1)
>>> print t
1
好像哪裡不對!t 不是 tuple ,而是整數1。為什麼呢?

因為()既可以表示tuple,又可以作為括弧表示運算時的優先順序,結果 (1) 被Python解釋器計算出結果 1,導致我們得到的不是tuple,而是整數 1。

正是因為用()定義單元素的tuple有歧義,所以 Python 規定,單元素 tuple 要多加一個逗號“,”,這樣就避免了歧義:

>>> t = (1,)
>>> print t
(1,)
Python在列印單元素tuple時,也自動添加了一個“,”,為了更明確地告訴你這是一個tuple。

“可變的tuple”

前面我們看到了tuple一旦創建就不能修改。現在,我們來看一個“可變”的tuple:

>>> t = ('a', 'b', ['A', 'B'])

註意到 t 有 3 個元素:'a','b'和一個list:['A', 'B']。list作為一個整體是tuple的第3個元素。list對象可以通過 t[2] 拿到:

>>> L = t[2]
然後,我們把list的兩個元素改一改:

>>> L[0] = 'X'
>>> L[1] = 'Y'

再看看tuple的內容:

>>> print t
('a', 'b', ['X', 'Y'])

條件判斷和迴圈

if語句

for迴圈

L = ['Adam', 'Lisa', 'Bart']
for name in L:
    print name

### while迴圈

while x < N:
print x
x = x + 1

break與continue

在迴圈過程中,可以用break退出當前迴圈,還可以用continue跳過後續迴圈代碼,繼續下一次迴圈。

多重迴圈

Dict和Set類型

什麼是dict

用 dict 表示“名字”-“成績”的查找表如下:

d = {
    'Adam': 95,
    'Lisa': 85,
    'Bart': 59
}

我們把名字稱為key,對應的成績稱為value,dict就是通過 key 來查找 value。

花括弧 {} 表示這是一個dict,然後按照 key: value, 寫出來即可。最後一個 key: value 的逗號可以省略。

訪問dict

d[key] 的形式來查找對應的 value,這和 list 很像,不同之處是,list 必須使用索引返回對應的元素,而dict使用key:

註意: 通過 key 訪問 dict 的value,只要 key 存在,dict就返回對應的value。如果key不存在,會直接報錯:KeyError。

要避免 KeyError 發生,有兩個辦法:

  • 一是先判斷一下 key 是否存在,用 in 操作符:
if 'Paul' in d:
    print d['Paul']

如果 'Paul' 不存在,if語句判斷為False,自然不會執行 print d['Paul'] ,從而避免了錯誤。

  • 二是使用dict本身提供的一個 get 方法,在Key不存在的時候,返回None:
>>> print d.get('Bart')
59
>>> print d.get('Paul')
None

dict的特點

  • 查找速度快,無論dict有10個元素還是10萬個元素,查找速度都一樣。而list的查找速度隨著元素增加而逐漸下降。

不過dict的查找速度快不是沒有代價的,**dict的缺點是占用記憶體大,還會浪費很多內容,list正好相反,占用記憶體小,但是查找速度慢。

  • 由於dict是按 key 查找,所以,在一個dict中,key不能重覆。

  • 存儲的key-value序對是沒有順序的!這和list不一樣:

d = {
    'Adam': 95,
    'Lisa': 85,
    'Bart': 59
}

當我們試圖列印這個dict時:

>>> print d
{'Lisa': 85, 'Adam': 95, 'Bart': 59}
列印的順序不一定是我們創建時的順序,而且,不同的機器列印的順序都可能不同,這說明dict內部是無序的,不能用dict存儲有序的集合。
  • **是作為 key 的元素必須不可變,Python的基本類型如字元串、整數、浮點數都是不可變的,都可以作為 key。但是list是可變的,就不能作為 key。

可以試試用list作為key時會報什麼樣的錯誤。

不可變這個限制僅作用於key,value是否可變無所謂:

{
'123': [1, 2, 3], # key 是 str,value是list
123: '123', # key 是 int,value 是 str
('a', 'b'): True # key 是 tuple,並且tuple的每個元素都是不可變對象,value是 boolean
}
最常用的key還是字元串,因為用起來最方便。

更新dict

要把新同學'Paul'的成績 72 加進去,用賦值語句:

>>> d['Paul'] = 72

遍歷dict

直接使用for迴圈可以遍歷 dict 的 key:

>>> d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 }
>>> for key in d:
...     print key
... 
Lisa
Adam
Bart

什麼是set

dict的作用是建立一組 key 和一組 value 的映射關係,dict的key是不能重覆的。

有的時候,我們只想要 dict 的 key,不關心 key 對應的 value,目的就是保證這個集合的元素不會重覆,這時,set就派上用場了。

set 持有一系列元素,這一點和 list 很像,但是set的元素沒有重覆,而且是無序的,這點和 dict 的 key很像。

所以set可以作為dict的key

訪問set

訪問 set中的某個元素實際上就是判斷一個元素是否在set中。

例如,存儲了班裡同學名字的set:

`>>> s = set(['Adam', 'Lisa', 'Bart', 'Paul'])
我們可以用 **in **操作符判斷:

Bart是該班的同學嗎?

>>> 'Bart' in s
True

set的特點

  • set的內部結構和dict很像,唯一區別是不存儲value,因此,判斷一個元素是否在set中速度很快。

  • set存儲的元素和dict的key類似,必須是不變對象,因此,任何可變對象是不能放入set中的。

  • set存儲的元素也是沒有順序的。

遍歷set

由於 set 也是一個集合,所以,遍歷 set 和遍歷 list 類似,都可以通過 for 迴圈實現。

直接使用 for 迴圈可以遍歷 set 的元素:

>>> s = set(['Adam', 'Lisa', 'Bart'])
>>> for name in s:
...     print name
... 
Lisa
Adam
Bart

更新set

添加元素時,用set的add()方法:

>>> s = set([1, 2, 3])
>>> s.add(4)
>>> print s
set([1, 2, 3, 4])

如果添加的元素已經存在於set中,add()不會報錯,但是不會加進去了:

>>> s = set([1, 2, 3])
>>> s.add(3)
>>> print s
set([1, 2, 3])

刪除set中的元素時,用set的remove()方法:

>>> s = set([1, 2, 3, 4])
>>> s.remove(4)
>>> print s
set([1, 2, 3])

如果刪除的元素不存在set中,remove()會報錯:

>>> s = set([1, 2, 3])
>>> s.remove(4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 4

所以用add()可以直接添加,而remove()前需要判斷。

函數

什麼是函數

調用函數

編寫函數

返回多值

>>> r = move(100, 100, 60, math.pi / 6)
>>> print r
(151.96152422706632, 70.0)

Python的函數返回多值其實就是返回一個tuple,但寫起來更方便。

遞歸函數

漢諾塔

定義預設參數

定義可變參數

如果想讓一個函數能接受任意個參數,我們就可以定義一個可變參數:

def fn(*args):
    print args

可變參數也不是很神秘,Python解釋器會把傳入的一組參數組裝成一個tuple傳遞給可變參數,因此,在函數內部,直接把變數 args 看成一個 tuple 就好了。

切片

對list進行切片

取前N個元素,也就是索引為0-(N-1)的元素,可以用迴圈:

>>> r = []
>>> n = 3
>>> for i in range(n):
...     r.append(L[i])
... 
>>> r
['Adam', 'Lisa', 'Bart']

對這種經常取指定索引範圍的操作,用迴圈十分繁瑣,因此,Python提供了切片(Slice)操作符,能大大簡化這種操作。

對應上面的問題,取前3個元素,用一行代碼就可以完成切片:

>>> L[0:3]
['Adam', 'Lisa', 'Bart']
L[0:3]表示,從索引0開始取,直到索引3為止,但不包括索引3。即索引0,1,2,正好是3個元素

只用一個 : ,表示從頭到尾:

>>> L[:]
['Adam', 'Lisa', 'Bart', 'Paul']
因此,L[:]實際上複製出了一個新list。

切片操作還可以指定第三個參數:

>>> L[::2]
['Adam', 'Bart']
第三個參數表示每N個取一個,上面的 L[::2] 會每兩個元素取出一個來,也就是隔一個取一個。

把list換成tuple,切片操作完全相同,只是切片的結果也變成了tuple。

倒序切片

對字元串切片

字元串 'xxx'和 Unicode字元串 u'xxx'也可以看成是一種list,每個元素就是一個字元。因此,字元串也可以用切片操作,只是操作結果仍是字元串

迭代

什麼是迭代

在Python中,如果給定一個list或tuple,我們可以通過for迴圈來遍歷這個list或tuple,這種遍歷我們成為迭代(Iteration)。

在Python中,迭代是通過 for ... in 來完成的

因為 Python 的 for迴圈不僅可以用在list或tuple上,還可以作用在其他任何可迭代對象上。

因此,迭代操作就是對於一個集合,無論該集合是有序還是無序,我們用 for 迴圈總是可以依次取出集合的每一個元素。

註意: 集合是指包含一組元素的數據結構,我們已經介紹的包括:

  1. 有序集合:list,tuple,str和unicode;
  2. 無序集合:set
  3. 無序集合併且具有 key-value 對:dict
    而迭代是一個動詞,它指的是一種操作,在Python中,就是 for 迴圈。

索引迭代

**Python中,迭代永遠是取出元素本身,而非元素的索引。

對於有序集合,元素確實是有索引的。有的時候,我們確實想在 for 迴圈中拿到索引,怎麼辦?

方法是使用 enumerate() 函數:

>>> L = ['Adam', 'Lisa', 'Bart', 'Paul']
>>> for index, name in enumerate(L):
...     print index, '-', name
... 
0 - Adam
1 - Lisa
2 - Bart
3 - Paul

迭代dict的value

dict 對象有一個 values() 方法,這個方法把dict轉換成一個包含所有value的list,這樣,我們迭代的就是 dict的每一個 value:

d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 }
print d.values()
# [85, 95, 59]
for v in d.values():
    print v
# 85
# 95
# 59

如果仔細閱讀Python的文檔,還可以發現,dict除了values()方法外,還有一個 itervalues() 方法,用 itervalues() 方法替代 values() 方法,迭代效果完全一樣:

*那這兩個方法有何不同之處呢?

  1. values() 方法實際上把一個 dict 轉換成了包含 value 的list。

  2. 但是 itervalues() 方法不會轉換,它會在迭代過程中依次從 dict 中取出 value,所以 itervalues() 方法比 values() 方法節省了生成 list 所需的記憶體。

  3. 列印 itervalues() 發現它返回一個 <dictionary-valueiterator> 對象,這說明在Python中,for 迴圈可作用的迭代對象遠不止 list,tuple,str,unicode,dict等,任何可迭代對象都可以作用於for迴圈,而內部如何迭代我們通常並不用關心。

迭代dict的key和value

items() 方法把dict對象轉換成了包含tuple的list,我們對這個list進行迭代,可以同時獲得key和value:

>>> for key, value in d.items():
...     print key, ':', value
... 
Lisa : 85
Adam : 95
Bart : 59

和 values() 有一個 itervalues() 類似, items() 也有一個對應的 iteritems(),iteritems() 不把dict轉換成list,而是在迭代過程中不斷給出 tuple,所以, iteritems() 不占用額外的記憶體。

列表生成式

生成列表

要生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],我們可以用range(1, 11):

>>> range(1, 11)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

但如果要生成[1x1, 2x2, 3x3, ..., 10x10]怎麼做?方法一是迴圈:

>>> L = []
>>> for x in range(1, 11):
...    L.append(x * x)
... 
>>> L
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

但是迴圈太繁瑣,而列表生成式則可以用一行語句代替迴圈生成上面的list:

>>> [x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

這種寫法就是Python特有的列表生成式。利用列表生成式,可以以非常簡潔的代碼生成 list。

複雜表達式

假設有如下的dict:

d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 }

完全可以通過一個複雜的列表生成式把它變成一個 HTML 表格:

tds = ['<tr><td>%s</td><td>%s</td></tr>' % (name, score) for name, score in d.iteritems()]
print '<table>'
print '<tr><th>Name</th><th>Score</th><tr>'
print '\n'.join(tds)
print '</table>'

字元串的join()方法可以把一個 list 拼接成一個字元串

條件過濾

列表生成式的 for 迴圈後面還可以加上 if 判斷。例如:

>>> [x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]

有了 if 條件,只有 if 判斷為 True 的時候,才把迴圈的當前元素添加到列表中。

多層表達式

for迴圈可以嵌套,因此,在列表生成式中,也可以用多層 for 迴圈來生成列表。

對於字元串 'ABC' 和 '123',可以使用兩層迴圈,生成全排列:

>>> [m + n for m in 'ABC' for n in '123']
['A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3']

翻譯成迴圈代碼就像下麵這樣:

L = []
for m in 'ABC':
    for n in '123':
        L.append(m + n)

最後註意:不管你是為了Python就業還是興趣愛好,記住:項目開發經驗永遠是核心,如果你沒有2020最新python入門到高級實戰視頻教程,可以去小編的Python交流.裙 :七衣衣九七七巴而五(數字的諧音)轉換下可以找到了,裡面很多新python教程項目,還可以跟老司機交流討教!
本文的文字及圖片來源於網路加上自己的想法,僅供學習、交流使用,不具有任何商業用途,版權歸原作者所有,如有問題請及時聯繫我們以作處理。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 定時器功能分析 核心思路: 定義一個變數,根據定時器,每秒執行一次,每次執行++自增操作 變數存儲的數值,就會每秒+1 現在需要的記錄效果,是每0.01秒,也就是10毫秒執行一次 根據累計的數值,執行進位 ms 如果達到 100,就是1秒 如果 秒 達到 60 就是 1分鐘 如果 分鐘 達到 60  ...
  • JavaScript與函數式編程 絕大多數編程語言都會有函數的概念(或者說所有的?我不太確定),他們都可以做出類似的操作: 但是Javascript更適合函數式編程,因為函數對於js來說,是 一等公民 。 我們可以把匿名函數賦值給一個變數,比如: 然後我們可以將這個函數賦值給另一個變數: 這樣做和直 ...
  • 在 JavaScript 中,new 運算符創建一個用戶定義的對象類型的實例或具有構造函數的內置對象的實例。創建一個對象很簡單,為什麼我們還要多此一舉使用 new 運算符呢?它到底有什麼樣的魔力? ...
  • 判斷input上傳文件類型,文件大小。input獲取的size為位元組,判斷大小的時候需要把限制大小轉換為位元組 ...
  • 前情提要: 現有一個網站框架,包括主體項目WebApp一個,包含 IIdentityUser 介面的基架項目 A。用於處理用戶身份驗證的服務 AuthenticationService 位於命名空間B。用於保存數據的實體 User : IIdentityUser 位置項目C。項目之間的關係是B和C依 ...
  • 1 簡介 是最簡單的使用 的方式,而 是最流行的 資料庫。兩者在分散式、微服務架構中使用率極高,本文將用實例介紹如何在 中整合 的兩種方法: 和`MongoTemplate`。 代碼結構如下: 2 項目準備 2.1 啟動MongoDB實例 為了方便,使用 來啟動 ,詳細指導文檔請參考: "用Dock ...
  • 知識無界 記錄tomcat和mybatis源碼導入到eclipse的過程 開發這麼久了,不能老crud,看看人家的源碼和設計思路。 0. tomcat源碼導入eclipse 下載tomcat源碼https://github.com/apache/tomcat, 然後按步驟下載(也可用git clon ...
  • springboot 項目使用阿裡雲簡訊服務發送手機驗證碼 (第一篇) 1、註冊阿裡雲賬戶進行賬號實名認證 2、申請簡訊簽名和模板 3、創建access_key和access_secret 4、然後就是代碼編寫 一、找到產品與服務裡面的雲通信模塊,然後找到簡訊服務,開通簡訊服務。我這裡已經開通,可直 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...