Python 3 快速入門 1 —— 數據類型與變量


本文假設你已經有一門面向對象編程語言基礎,如Java等,且希望快速了解並使用Python語言。本文對重點語法和數據結構以及用法進行詳細說明,同時對一些難以理解的點進行了圖解,以便大家快速入門。一些較偏的知識點在大家入門以后根據實際需要再查詢官方文檔即可,學習時切忌胡子眉毛一把抓。同時,一定要跟着示例多動手寫代碼。學習一門新語言時推薦大家同時去刷leetcode,一來可以快速熟悉新語言的使用,二來也為今后找工作奠定基礎。推薦直接在網頁上刷leetcode,因為面試的時候一般會讓你直接在網頁編寫代碼。leetcode刷題路徑可以按我推薦的方式去刷。以下代碼中,以 >>>... 開頭的行是交互模式下的代碼部分,>?開頭的行是交互模式下的輸入,其他行是輸出。python代碼中使用 #開啟行注釋。

Python 簡介

Python作為一門腳本語言,既可以在命令行以交互的方式進行程序編寫和執行,也可以在*.py文件中進行編寫然后通過解釋器執行。前者適合驗證階段使用,后者更適合項目編寫。(驗證階段更推薦使用Jupyter,在編寫時可將順序執行的代碼人為的划分為相鄰的代碼塊,執行時可以手動依次執行代碼塊,當某一個代碼塊出現錯誤時,修改了出錯的代碼塊后無需再次重頭執行,只需從修改處代碼塊接着執行即可。)

在學習的過程中,通過help()函數可以查看方法、對象等的官方文檔。例如查看print函數的官方文檔:

>>> help(print)
Help on built-in function print in module builtins:
print(...)
    print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
    
    Prints the values to a stream, or to sys.stdout by default.
    Optional keyword arguments:
    file:  a file-like object (stream); defaults to the current sys.stdout.
    sep:   string inserted between values, default a space.
    end:   string appended after the last value, default a newline.
    flush: whether to forcibly flush the stream.

基本輸入輸出

輸出:print()函數:

>>> print("sum( a + b ):", 10 + 20)
sum( a + b ): 30

如上,print 函數將前面的字符串和后面的計算結果通過空格拼接成字符串。你也可以指定sep = "\n"參數讓其通過換行符拼接。如下:

>>> print("sum( a + b ): ", 10 + 20, sep = "\n")
sum( a + b ): 
30

輸入:input()函數,該函數默認將所有讀入的數據視為字符串:

>>> a = input()
>>> print(a)
>>> print(type(a))
>? 123
123
<class 'str'="">

數據類型和變量

數值型( immutable )

int   # 整型
float # 浮點型
bool  # 布爾型
complex  # 復數,需要時查詢文檔即可,這里不做講解

Python 作為動態語言,在定義變量時無需指定數據類型,執行時解釋器會自行推斷出變量類型。在PycharmPython Console選項卡(建立項目后才可以看到,在界面的最下面一行)里可以實時顯示變量的類型:

image-20211120165750940

Python 中除法默認返回浮點數,使用雙斜杠除法//會舍去小數點后面的部分:

>>> a = 3       # 在交互模式下點擊shift+enter可以實現多行代碼編寫
... b = 4
... print(a/b) 
0.75            # / 除法返回浮點數

>>> print(a//b)
0               # // 除法舍去小數部分

>>> a = 3.0
... b = 4.0
... print(a/b)
0.75

>>> print(a//b)
0.0

Python語言中使用 **表示冪次計算,如 2 的 3 次方寫為:2 ** 3

>>> print(2 ** 3)
8

Python語言中的 bool 類型分為TrueFalse(嚴格區分大小寫),bool 類型是 int 類型的子類,且True在值上等於1False在值上等於0

>>> True == 1
True
>>> False == 0
True
>>> issubclass(bool, int)
True

提示:Python中的數值類型是引用類型而不是值類型

字符串型(immutable )

str   # 字符串型

Python中被''""引住的內容表示一個字符串,Python中的字符串與Java中的字符一樣為不可變( immutable )類型。如下:

image-20211120172106079

Python字符串的強大之處在於支持下標訪問切片功能。通過下標訪問我們可以直接拿到字符串中的某個字符(實際為只有一個字符構成的字符串),當下標為負數時表示從右側開始:

image-20211120174342817

通過切片操作,我們可以獲取某個字符串的任意子串,切片由一個區間表示,如[0: len]表示獲取下標0 - len-1的子串,即左閉右開。此外[:3]等同[0: 3][3:]等同[3: len]。由於每次切片操作都會返回一個新的字符串

>>> a = 'python'

>>> print(a[:3])
pyt
>>> print(a[0: 3])
pyt

>>> print(a[3:])
hon
>>> print(a[3: len(a)])
hon

>>> print(a[:-3])  # 從開頭到倒數第三個字符表示的子串(同樣符合左閉右開)
pyt
>>> print(a[-3:])
hon

Python還支持多行字符串,需要時查詢文檔即可。

列表類型(mutable)

list  # 列表

Python 中的列表有點類似於 JavaList接口的實現(ArryListLinkedList),是一種高級數據結構,不同之處在於 Python 中的 list 可以存儲不同類型的數據,但通常並不會這樣使用。list 還支持切片操作,且是可變( mutable)類型。list 由中括號包住若干被逗號分隔的元素來表示,如:[1, 2, 3]

由於list是可變類型,我們可以對list進行修改:

>>> a = ['p', 'y', 't', 'h', 'o', 'n']
>>> a[1] = 'i'                  # 將下標1中的元素(引用)指向字符串'i'
>>> print(a)
['p', 'i', 't', 'h', 'o', 'n']  # 第2個元素(引用)指向的字符串對象由 'y' 變為 'i'

list 的切片操作返回的新列表是原列表的一個淺拷貝。淺拷貝是對象拷貝的一種方式,由於Python中只有引用類型,下面以list類型為例對引用類型的淺拷貝進行講解。下圖是列表 a 在內存中的示意圖:

python-list內存分布

變量a是一個引用(地址),它指向內存中的list對象。list對象中的每一個元素(引用)又指向內存中的int對象。當對a執行如下切片操作時:

>>> a = [1, 2, 3, 4]
>>> b = a[:2]  # 1. b通過切片獲取a前兩個元素的淺拷貝
>>> print(a)
... print(b)
[1, 2, 3, 4]
[1, 2]
>>> b[0] = 6   # 2. 修改b[0]
>>> print(a)
... print(b) 
[1, 2, 3, 4]   # 修改b[0]並沒有影響a,為什么呢?
[6, 2]

執行 b = a[:2]時,內存中會生成一個新的list對象,且b會指向這個新list對象,內存變化如下:

image-20211122115033653

執行b[0] = 6時,內存變化如下:

image-20211122115835385

由上圖容易知道這種情況下修改b並不會影響a。接着往下看:

>>> a = [1, 2, 3, [0, 0]]
>>> b = a[-2:]     # b通過切片獲取a后兩個元素的淺拷貝
>>> print(a)
... print(b)
[1, 2, 3, [0, 0]]
[3, [0, 0]]
>>> b[1][0] = 6    # 修改b[1][0]
>>> print(a)
... print(b)
[1, 2, 3, [6, 0]]  # 修改b[1][0]時,影響了a
[3, [6, 0]]

執行b = a[-2:]時,內存變化如下:

image-20211122134618255

執行b[1][0] = 6時,內存變化如下:

image-20211122154441339

由上圖容易知道,因為a[3]b[1]指向內存中同一個list,當通過b[1][0]修改b時會同時影響a

同時,我們還可以通過切片操作來修改列表:

>>> a = [1, 2, 3]
>>> a[1: 3] = [6, 6]  # 修改a中后兩個元素;如果這里為a[1: 3] = [6, 6, 6, 6]會出錯嗎?動手試試
>>> print(a)
[1, 6, 6]

>>> a[:] = []         # 清空a
>>> print(a)
[]

此外,列表還支持合並與嵌套:

>>> a = [1, 2, 3]
>>> b = [4, 5, 6]
>>> c = a + b           # 合並
>>> print(c)
[1, 2, 3, 4, 5, 6]

>>> d = [a, b]          # 嵌套
>>> print(d)
[[1, 2, 3], [4, 5, 6]] 

最后,列表還提供了一系列成員方法:

  • list.append(x)
    在列表末尾添加一個元素,相當於 a[len(a):] = [x]

    >>> a = ['wjz']
    >>> a.append('lsl')
    >>> print(a)
    ['wjz', 'lsl']
    
  • list.extend(iterable)
    用可迭代對象的元素擴展列表。相當於 a[len(a):] = iterable

    >>> a = [1, 2, 3]
    ... b = [4, 5, 6]
    ... a.extend(b)
    ... print(a)
    [1, 2, 3, 4, 5, 6]
    
  • list.insert(i, x)
    在指定位置插入元素。第一個參數是插入元素的索引,因此,a.insert(0, x) 在列表開頭插入元素, a.insert(len(a), x) 等同於 a.append(x)

  • list.remove(x)
    從列表中刪除第一個值為 x 的元素。未找到指定元素時,觸發 ValueError 異常。

  • list.pop([i])
    刪除列表中指定位置的元素,並返回被刪除的元素。未指定位置時,a.pop() 刪除並返回列表的最后一個元素。(方法簽名中 i 兩邊的方括號表示該參數是可選的,不是要求輸入方括號。這種表示法常見於 Python 參考庫)。

    >>> a = [1, 2, 3]
    >>> a.pop()   # 默認為 pop(-1),即倒數第一個
    3
    >>> print(a)
    [1, 2]
    >>> a.pop(0)  # 刪除第一個
    1
    >>> print(a)
    [2]
    
  • list.clear()
    刪除列表里的所有元素,相當於 del a[:]del語句可以刪除一個變量,或按切片刪除列表元素。

    # 刪除變量
    >>> a = [1, 2, 3]
    ... b = a
    ... del a
    ... print(a)  # 刪除變量a后再訪問a,報錯:未定義
    Traceback (most recent call last):
      File "<input>", line 4, in <module>
    NameError: name 'a' is not defined
    >>> print(b)  # b引用指向的列表對象還存在說明del只是刪除了a這個引用
    [1, 2, 3]
    
    # del通過切片刪除列表元素
    >>> a = [1, 2, 3]
    ... del a[:2]
    ... print(a)
    [3]
    
  • list.index(x[, start[, end]])
    返回列表中第一個值為 x 的元素的零基索引。未找到指定元素時,觸發 ValueError 異常。可選參數 startend 是切片符號,用於將搜索限制為列表的特定子序列。返回的索引是相對於整個序列的開始計算的,而不是 start 參數。

    >>> a = [1, 2, 3, 4, 5]
    ... print(a.index(3))
    2  # a中3的下標為2
    
    >>> a = [1, 2, 3, 4, 5]
    ... print(a.index(3, 2, len(a)))  # 從第3個元素開始查找3
    2
    
  • list.count(x)
    返回列表中元素 x 出現的次數。

  • list.sort(*, key=None, reverse=False)
    就地排序列表中的元素(要了解自定義排序參數,詳見 sorted())。該方法先忽略,入門2中有講解。

  • list.reverse()
    翻轉列表中的元素。

  • list.copy()
    返回列表的淺拷貝。相當於 a[:]

元組類型(immutable )

tuple  # 元組

元組與列表很相似,但元組為不可變類型,元組通常用來包含異質元素(類型不同)而列表通常用來包含同質元素。tuple 由小括號包住若干被逗號分隔的元素來表示,如:(1, 2, 3)。元組同樣支持切片、下標(索引)訪問。

定義一個元組:

>>> a = (1, 2, 3)
>>> b = 1, 2, 3  # 定義時省略括號也行,但不建議
>>> print(a, b)
(1, 2, 3) (1, 2, 3)

# 定義一個空元組
>>> a = ()
... print(a)
()

# 定義只有一個元素的元組
>>> a = (1,)
... print(type(a))
... print(a)
<class 'tuple'="">
(1,)

# 沒有逗號 a 就是值為 1 的int型變量
>>> a = (1)
... print(type(a))
... print(a)
<class 'int'="">
1

元組的不可變是指元組中的每一個元素(引用)的指向不能改變,以a = (1, 2, 3, 4)為例:

image-20211126164823623

上圖中被橢圓圈起來的四個指向都不能修改,但如果元組中元素(引用)指向的是一個可變類型,指向雖然不能修改,但可變類型本身是可以修改的,以a = ([1, 2], [3, 4])為例:

image-20211126170343296

上圖中被紅色橢圓圈起來的指向不能修改,被藍色橢圓圈起來的指向可以修改:

>>> a = (1, 2, 3, 4)
>>> a[0] = 6  # 不能修改a[0]的指向
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

>>> a = ([1, 2], [3, 4])
>>> a[0] = [6, 6]  # 不能修改a[0]的指向
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> a[0][0] = 6    # a[0] 指向的list可以修改
>>> print(a)
([6, 2], [3, 4])

集合類型(mutable)

set  # 集合類型

集合是用來存放不含重復元素的無序容器。

定義集合:

# 通過花括號定義集合
>>> a = {1, 2, 3, 2}
... print(a)
{1, 2, 3}  # 去重

# 通過set()函數定義集合。只能傳入一個參數,且為可迭代類型。
# 會取出可迭代類型中的每一個元素為一個集合元素
>>> set("123 4")  # 傳入字符串
{'3', ' ', '2', '4', '1'}
>>> set(["1", "2", "3"])  # 傳入list
{'3', '1', '2'}

# 定義空集合只能使用set()函數
>>> a = set()
... print(type(a))
... print(a)
<class 'set'="">
set()

# {}表示一個空字典
>>> a = {}
... print(type(a))
... print(a)
<class 'dict'="">
{}

字典類型(mutable)

dict  # 字典

字典類型是可變類型,類似與Java中的Map。字典類型用來存儲鍵值對,關鍵字通常是字符串或數字,也可以是其他任意不可變類型。若元組直接或間接地包含了可變對象,就不能用作關鍵字。

創建字典:

# 創建空字典
>>> a = {}
>>> print(a)
{}
>>> a = dict()
>>> print(a)
{}

# 常用創建方式
# 直接在花括號中申明鍵值對
>>> a = {"chengdu": "A", "mianyang": "B", "guangyuan": "C"}
>>> print(a)
{'chengdu': 'A', 'mianyang': 'B', 'guangyuan': 'C'}

# 關鍵字傳參的方式調用dict函數
>>> a = dict(chengdu="A", mianyang="B", guangyuan="C")
>>> print(a)
{'chengdu': 'A', 'mianyang': 'B', 'guangyuan': 'C'}

# 構造函數中傳入鍵值對序列
>>> a = dict((("chengdu", "A"), ("mianyang", "B"), ("guangyuan", "C")))
>>> print(a)
{'chengdu': 'A', 'mianyang': 'B', 'guangyuan': 'C'}

>>> a = dict([("chengdu", "A"), ("mianyang", "B"), ("guangyuan", "C")])
>>> print(a)
{'chengdu': 'A', 'mianyang': 'B', 'guangyuan': 'C'}

>>> a = dict([["chengdu", "A"], ["mianyang", "B"], ["guangyuan", "C"]])
>>> print(a)
{'chengdu': 'A', 'mianyang': 'B', 'guangyuan': 'C'}

對字典進行增刪改:

>>> a = dict([["chengdu", "A"], ["mianyang", "B"], ["guangyuan", "C"]])
>>> a["zigong"] = "C"  # 為不存在的key賦值即可添加新的鍵值對
... print(a)
{'chengdu': 'A', 'mianyang': 'B', 'guangyuan': 'C', 'zigong': 'C'}

>>> del a["zigong"]    # 刪除key為 “zigong” 的鍵值對
... print(a)
{'chengdu': 'A', 'mianyang': 'B', 'guangyuan': 'C'}

>>> a["guangyuan"] = "F"  # 為已經存在的key賦值即可對已存在的鍵值對進行修改
... print(a)
{'chengdu': 'A', 'mianyang': 'B', 'guangyuan': 'F'}

常用高級數據結構

棧的特性是先進后出,使用list非常容易實現;使用append(e)將元素添加到棧頂,使用pop()將棧頂元素彈出:

>>> stack = [1, 2, 3]
>>> stack.append(4)  # 4入棧
... print(stack)
[1, 2, 3, 4]

>>> stack.pop()  # 4出棧
... stack.pop()  # 3出棧
... print(stack)
[1, 2]

隊列

隊列的特性是先進先出,使用list也能實現隊列,即使用append(e)將元素入隊尾,使用pop(0)使隊頭元素出隊。但pop(0)操作很費時(其他元素都必須向前移動一位),故不推薦使用list實現隊列。

實現隊列最好用 collections.deque,可以快速從兩端添加或刪除元素(雙端隊列):

  • append():從右邊入隊
  • appendleft():從左邊入隊
  • popleft():從左邊出隊
  • pop():從右邊出隊
>>> from collections import deque
... myDeque = deque([1, 2, 3])
... print(myDeque)
... myDeque.append(4)  # 4入隊尾
... print(myDeque)
... myDeque.popleft()  # 1出隊頭
... print(myDeque)
deque([1, 2, 3])
deque([1, 2, 3, 4])
deque([2, 3, 4])


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM