python的一些常用簡易技術(一)

jpx發表於2024-07-16

一、python的一些資料結構

0、字串:python 字串是不可變的,意味著一旦字串被建立,其內容就不能被改變。但Python 中的字串變數的存在,是因為字串變數實際上是指向字串物件的引用,而不是字串本身。

# 字串的不可變性質
s = "hello"
s[0] = "H"  # 這會引發 TypeError,因為字串是不可變的

# 變數的引用
s = "hello"
print(s)  # 輸出: hello
# 重新分配變數
s = "world"
print(s)  # 輸出: world

# 將字串中的所有字母轉換為大寫
s = "hello"
print(s.upper())  # 輸出: "HELLO"

# 將字串中的所有字母轉換為小寫
s = "HELLO"
print(s.lower())  # 輸出: "hello"

# 返回子字串在字串中第一次出現的位置(序號)。如果未找到子字串,則返回 -1
s = "hello world"
print(s.find("world"))  # 輸出: 6
print(s.find("Python"))  # 輸出: -1

# 返回子字串在字串中最後一次出現的位置(序號)。如果未找到子字串,則返回 -1
s = "hello world world"
print(s.rfind("world"))  # 輸出: 12

# 將字串中的某個子字串替換為另一個子字串
s = "hello world"
print(s.replace("world", "Python"))  # 輸出: "hello Python"

# 將字串拆分為列表。預設情況下,按空格拆分
s = "hello world"
print(s.split())  # 輸出: ['hello', 'world']

# 按行分割字串,返回一個包含各行的列表
s = "hello\nworld"
print(s.splitlines())  # 輸出: ['hello', 'world']

# 將列表中的字串連線成一個字串,連線符是源字串
words = ["hello", "world"]
print(" ".join(words))  # 輸出: "hello world"

# 移除字串開頭和結尾的空白字元
s = "  hello world  "
print(s.strip())  # 輸出: "hello world"

# 檢查字串是否只包含字母
s = "hello"
print(s.isalpha())  # 輸出: True
s = "hello123"
print(s.isalpha())  # 輸出: False

# 檢查字串是否只包含數字
s = "123"
print(s.isdigit())  # 輸出: True
s = "123abc"
print(s.isdigit())  # 輸出: False

# 檢查字串是否只包含字母和數字
s = "hello123"
print(s.isalnum())  # 輸出: True
s = "hello 123"
print(s.isalnum())  # 輸出: False

1、列表:一種有序的、可變的集合,允許重複元素,接近陣列概念。列表的索引,從序號:0開始。

# 建立一個空列表
my_list = []

# 建立一個包含初始元素的列表
my_list = [1, 2, 3, 4]

# 將元素新增到列表的末尾
my_list.append(4)

# 在索引1的位置插入'a'
my_list.insert(1, 'a')

# 將另一個列表的所有元素新增到當前列表的末尾
my_list.extend([4, 5])

# 移除列表中第一個匹配的元素
my_list.remove(2)

# 移除並返回指定位置的元素(預設是最後一個元素)
element = my_list.pop()
print(element)

# 移除列表中的所有元素
my_list.clear()

# 透過索引修改元素
my_list[1] = 'b'

# 幾種常用切片
my_list = [1, 2, 3, 4, 5]
print(my_list[1:3])  # 輸出: [2, 3](不包括索引3的元素)
print(my_list[:3])  # 輸出: [1, 2, 3](從開始到索引3,不包括索引3)
print(my_list[2:])  # 輸出: [3, 4, 5](從索引2到末尾)
print(my_list[::2])  # 輸出: [1, 3, 5](步長為2)

# 返回第一個匹配元素的索引
index = my_list.index(2)

# 返回指定元素在列表中出現的次數
count = my_list.count(2)

# 對列表進行原地排序。該列表即已經按排序修改過了
my_list.sort()

# 反轉列表中的元素
my_list.reverse()

# 淺複製
my_list = [1, 2, 3]
new_list = my_list.copy()
print(new_list)  # 輸出: [1, 2, 3]

# join方法:將列表中的字串連線成一個字串。該方法通常用於處理字串列表
words = ["hello", "world"] sentence = " ".join(words)
print(sentence) # 輸出: "hello world"

# len:返回列表元素數量
print(len(my_list))

# min()和max()函式分別返回列表中的最小值和最大值,sum()函式返回列表中的所有元素和(數值型)
my_list = [1, 2, 3, 4, 5]
print(min(my_list)) # 輸出:1
print(max(my_list)) # 輸出:5
print(sum(my_list)) # 輸出:15

2、字典:是一種無序的、可變的鍵值對集合,使用鍵(key)來存取對應的值(value),字典中的鍵是唯一的,字典保持插入順序,但本質上是無序的(python3.7+)。

# 建立空字典
my_dict = {}

#
建立字典 my_dict = {"name": "xxx", "age": 25} # 查詢:根據key訪問值,get() print(my_dict["name"])
print(mydict.get("name", "default name"))

# 新增、修改:如果沒有這個鍵值對則是新增,如果有,則修改為當前設定值
my_dict["age"] = 26

# 透過update增加鍵值對,以及修改
my_dict.update({"age": 25, "city": "New York"})
# 刪除指定鍵值對
del my_dict["age"]

# 基礎方法
print(my_dict.keys())  # 返回所有鍵dict_keys(['name', 'age'])
print(my_dict.values())  # 返回所有值dict_keys(['xxx', 25])
print(my_dict.items())  # 返回所有鍵值對dict_keys([('name', 'xxx'), ('age', 25)])

# setdefault() 方法、fromkeys() 方法

3、集合:一種無序的、可變的不重複元素集合,可以新增或刪除元素,且元素沒有特定的順序,元素是唯一的,不重複。

# 建立空集合,或從其他可迭代物件(如列表、元組、字串)建立集合,或者建立一個空集合
my_set = set()
my_list = [1, 2, 3, 4, 4, 5]
my_set = set(my_list)
my_string = "hello"
my_set = set(my_string)

# 建立帶有初始元素的集合,和字典一樣都是用大括號
my_set = {1, 2, 3, 4}

# 集合中新增單個元素
my_set.add(5)

# 向集合中新增多個元素,可以是列表、元組、字串或其他集合。會將其他集合分解成單個不重複元素,新增進去
my_set.update([4, 5])
print(my_set)  # 輸出: {1, 2, 3, 4, 5}
my_set.update({6, 7})
print(my_set)  # 輸出: {1, 2, 3, 4, 5, 6, 7}
my_set.update("abc")
print(my_set)  # 輸出: {1, 2, 3, 4, 5, 6, 7, 'a', 'c', 'b'}

# remove:移除指定元素。如果元素不存在,會引發KeyError
# discard:移除指定元素。如果元素不存在,不會引發異常
# pop:移除並返回集合中的一個隨機元素。如果集合為空,會引發 KeyError
# clear:移除所有元素
my_set.remove(2)
my_set.discard(2)
ele = my_set.pop()
my_set.clear()

# 查詢:檢查元素是否在集合中
print(2 in my_set) # 輸出: True

# 判斷一個集合是否是另外集合的子集
set1 = {1, 2}
set2 = {1, 2, 3}
print(set1.issubset(set2))  # 輸出: True


# 集合計算:union,返回兩個集合的並集
set1 = {1, 2, 3}
set2 = {3, 4, 5}
print(set1.union(set2))  # 輸出: {1, 2, 3, 4, 5}

4、元組:種有序的、不可變的集合,允許重複元素,建立後不能修改,元素按照插入的順序儲存。

# 建立空元組
# 建立帶有初始元素的元組
empty_tuple = ()
print(empty_tuple)  # 輸出: ()

my_tuple = (1, 2, 3)
print(my_tuple)  # 輸出: (1, 2, 3)

# 不使用小括號
my_tuple = 1, 2, 3
print(my_tuple)  # 輸出: (1, 2, 3)

# 單元素元組
single_element_tuple = (1,)
print(single_element_tuple)  # 輸出: (1,)

# 使用 tuple() 建構函式,接受列表、字串等資料結構
# 從列表建立元組
my_list = [1, 2, 3]
my_tuple = tuple(my_list)
print(my_tuple)  # 輸出: (1, 2, 3)

# 從字串建立元組
my_string = "hello"
my_tuple = tuple(my_string)
print(my_tuple)  # 輸出: ('h', 'e', 'l', 'l', 'o')

# 訪問:透過索引訪問,正序,倒序
print(my_tuple[0])  
print(my_tuple[-1])

# 訪問:透過切片訪問
my_tuple = (1, 2, 3, 4, 5)
print(my_tuple[1:3])  # 輸出: (2, 3)
print(my_tuple[:2])  # 輸出: (1, 2)
print(my_tuple[2:])  # 輸出: (3, 4, 5)
print(my_tuple[::2])  # 輸出: (1, 3, 5)

# 解包
my_tuple = (1, 2, 3)
a, b, c = my_tuple
print(a, b, c)  # 輸出: 1 2 3

# 使用*號解包
my_tuple = (1, 2, 3, 4)
a, *b, c = my_tuple
print(a, b, c)  # 輸出: 1 [2, 3] 4

# 元組操作:合併
tuple1 = (1, 2)
tuple2 = (3, 4)
merged_tuple = tuple1 + tuple2

# 查詢,使用in
print(2 in my_tuple) # True/False

# 返回指定元素的第一個匹配項的索引,如果元素不存在,會引發 ValueError
my_tuple = (1, 2, 3, 2)
print(my_tuple.index(2))  # 輸出: 1

# 計數,返回指定元素在元組中出現的次數
my_tuple = (1, 2, 3, 2)
print(my_tuple.count(2))  # 輸出: 2

# len() :返回元組中元素的數量
print(len(my_tuple))

# max() 和 min():返回元組中的最大值和最小值
my_tuple = (1, 2, 3)
print(max(my_tuple))  # 輸出: 3
print(min(my_tuple))  # 輸出: 1

# sum():返回元組中所有元素的和(元素必須是數值型別)
my_tuple = (1, 2, 3)
print(sum(my_tuple))  # 輸出: 6

二、python多程序:庫multiprocessing,在一個Python程式中同時執行多個程序,每個程序都有自己的記憶體空間。透過multiprocessing模組建立多個程序,每個程序有獨立的GIL,可以在多個CPU核心上並行執行,從而克服GIL的限制。

對於python,主程序是程式開始執行時的第一個程序,負責啟動和管理所有的子程序。可以使用 if __name__ == '__main__' 識別主程序,或者透過 multiprocessing.current_process().name 獲取當前程序的資訊(識別主程序、子程序)

demo1:建立2個程序,兩個程序幾乎同時啟動,並各自列印自己的編號,等待2秒後,主程序列印結束訊息。這裡子程序執行完(阻塞),才會繼續走主程序。

import multiprocessing
import time

# 定義一個簡單的函式,用於程序執行
def worker(num):
    """執行緒工作函式"""
    print(f'Worker: {num}')
    time.sleep(2)  # 模擬耗時操作

if __name__ == '__main__':
    # 建立兩個程序
    processes = []
    for i in range(2):
        p = multiprocessing.Process(target=worker, args=(i,))
        processes.append(p)
        p.start()

    # 等待所有程序完成
    for p in processes:
        p.join()

    print("All processes are done.")

demo2:如果想建立出來的子程序不阻塞我們的主程序,將join語句去掉即可,然後主程序就會執行後面的語句了。非同步執行:主程序在啟動子程序後,立即繼續執行而不等待子程序完成。子程序完成後,會在後臺輸出其結束訊息。

demo3:如果子程序會返回一個value,主程序設計去等待子程序執行完返回value,列印出來。使用 multiprocessing 模組中的 Process 類和 Queue來實現。使用 multiprocessing.Queue 在子程序和主程序之間傳遞資料。子程序將結果放入佇列,主程序從佇列中獲取結果。

a. 使用 queue.get() 從佇列中獲取子程序的結果。這將阻塞主程序,直到子程序向佇列中放入資料。

b. 使用 p.join() 確保子程序完成執行。

c. 使用 multiprocessing.Queue 在子程序和主程序之間傳遞資料。子程序將結果放入佇列,主程序從佇列中獲取結果。

import multiprocessing
import time

def worker(queue):
    """子程序工作函式"""
    print(f"Worker process started with PID: {multiprocessing.current_process().pid}")
    time.sleep(10)  # 模擬一個耗時10秒的任務
    result = "Result from worker"
    queue.put(result)
    print("Worker process finished.")

if __name__ == '__main__':
    print(f"Main process PID: {multiprocessing.current_process().pid}")

    # 建立一個Queue,用於子程序向主程序傳遞資料
    queue = multiprocessing.Queue()

    # 建立子程序
    p = multiprocessing.Process(target=worker, args=(queue,))

    # 啟動子程序
    p.start()

    # 主程序繼續執行其他任務
    print("Main process is doing some work while waiting for the result from worker process.")

    # 等待子程序完成並獲取結果
    result = queue.get()  # 這將阻塞主程序,直到子程序向佇列中放入資料

    # 確保子程序完成
    p.join()

    print(f"Main process received result: {result}")
    print("Main process has finished.")

tips1:對於python多程序能夠在單核機器上執行,但是它們不會真正並行執行,因為單核機器一次只能執行一個程序。作業系統會透過程序切換(時間片輪轉)來實現“併發”執行。每個程序在短時間內執行一段時間,然後作業系統會暫停該程序並切換到下一個程序,如此迴圈,從而給人一種多個程序同時執行的錯覺。

tips2:全域性直譯器鎖(GIL):Python中的GIL限制了在同一時間只有一個執行緒可以執行Python位元組碼,多執行緒在CPU密集型任務中無法充分利用多核CPU的優勢。

三、python多執行緒

四、python非同步

五、python常用的併發

六、python模擬發http請求

七、python直連mysql

八、python連redis

九、python操作etcd

十、pytest的一些應用

相關文章