學習日志15 python

1?filter()?函數

filter(function, iterable)

filter函數是python中的高階函數, 第一個參數是一個篩選函數, 第二個參數是一個可迭代對象, 返回的是一個生成器類型, 可以通過next獲取值。

filter()?函數是 Python 內置的高階函數,其主要功能是對可迭代對象中的每個元素運用篩選函數進行判斷,然后把符合條件的元素以生成器的形式返回。下面為你詳細介紹它的用法和特性:

基礎語法

python

運行

filter(function, iterable)

這里的參數?function?是一個用于篩選元素的函數,它會返回布爾值;iterable?則是一個可迭代對象,像列表、元組、集合等都屬于此類。

核心特性

  1. 返回生成器filter()?返回的是一個生成器對象,這意味著它是惰性求值的,只有在需要的時候才會生成值,這樣能有效節省內存。
  2. 篩選邏輯:當?function?返回?True?時,對應的元素會被保留;若返回?False,則該元素會被過濾掉。要是?function?為?Nonefilter()?會保留?iterable?中所有布爾值為?True?的元素。

示例

示例 1:過濾偶數

python

運行

numbers = [1, 2, 3, 4, 5, 6]
evens = filter(lambda x: x % 2 == 0, numbers)print(list(evens))  # 輸出: [2, 4, 6]
示例 2:過濾空字符串

python

運行

words = ["hello", "", "world", "  ", None, "python"]
valid_words = filter(None, words)  # 不傳篩選函數時,會過濾掉布爾值為 False 的元素print(list(valid_words))  # 輸出: ['hello', 'world', 'python']
示例 3:使用生成器特性

python

運行

numbers = [1, 2, 3, 4, 5]
filtered = filter(lambda x: x > 3, numbers)print(next(filtered))  # 輸出: 4
print(next(filtered))  # 輸出: 5

替代實現

你也可以通過列表推導式或者生成器表達式來實現相同的篩選功能:

python

運行

# 列表推導式
evens = [x for x in numbers if x % 2 == 0]# 生成器表達式(更節省內存)
evens_gen = (x for x in numbers if x % 2 == 0)

總結

filter()?函數特別適合用于數據篩選場景,它返回的生成器能高效處理大規模數據。不過在 Python 3 中,需要注意?filter()?返回的不再是列表,而是生成器,這一點和 Python 2 有所不同。

filter返回符合后面表達式為真的部分

filter()?函數會保留?function?返回值為?True?的元素,過濾掉返回?False?的元素。具體規則如下:

  1. 當?function?是自定義函數或 lambda 時
    只有當函數對元素的計算結果為?True?時,該元素才會被保留。

    python

    運行

    numbers = [1, 2, 3, 4]
    result = filter(lambda x: x > 2, numbers)  # 保留大于 2 的數
    print(list(result))  # 輸出: [3, 4]
    
  2. 當?function?為?None?時
    會自動過濾掉任何布爾值為?False?的元素(如?None0、空字符串?""、空列表?[]?等)。

    python

    運行

    values = [0, "", None, "hello", 5]
    result = filter(None, values)  # 保留布爾值為 True 的元素
    print(list(result))  # 輸出: ['hello', 5]
    

底層邏輯

可以將?filter()?函數等價理解為一個生成器表達式:

python

運行

# 以下兩種寫法等價
filter(function, iterable)
(x for x in iterable if function(x))  # 當 function 不為 None 時
(x for x in iterable if x)            # 當 function 為 None 時

注意事項

返回值是生成器:需要用?list()?轉換為列表(或用?next()?逐個獲取值)。

函數參數的順序function?在前,iterable?在后,不要混淆。

以下代碼運行結果為:func = lambda x:x%2
result = filter(func, [1, 2, 3, 4, 5])
print(list(result))正確答案:[1,3,5]

2?在 Python 中,沒有單獨的?char(字符)類型

Python的主要內置數據類型包括:

?- 數值類型:int(整數)、float(浮點數)、complex(復數)

- 序列類型:list(列表)、tuple(元組)、range(范圍)

- 字符串類型:str - 映射類型:dict(字典)

- 集合類型:set(集合)、frozenset(不可變集合)

- 布爾類型:bool

- 空值類型:None

所以char并不在Python的數據類型體系中。

而是用長度為 1 的字符串?str?來表示單個字符。例如:

python

運行

char = 'A'  # 這是一個長度為 1 的字符串,而非 char 類型
print(type(char))  # 輸出: <class 'str'>

為什么 Python 沒有?char?類型?

  1. 字符串不可變:Python 的字符串是不可變序列,單個字符本質上就是長度為 1 的字符串,無需額外類型。
  2. Unicode 支持:Python 3 的?str?類型默認支持 Unicode,直接用?str?表示字符更符合國際化需求。
  3. 簡化設計:避免引入多余類型,保持語言簡潔性(如 Java 中?char?是基本類型,而 Python 一切皆對象)。

字符操作示例

雖然沒有?char?類型,但可以通過索引訪問字符串中的字符:

python

運行

s = "hello"
first_char = s[0]  # 'h'
print(type(first_char))  # <class 'str'>

與其他語言的對比

語言字符類型字符串類型
Pythonstr?(長度 = 1)str
JavacharString
C/C++charchar[]?或?std::string

如果你需要處理字符編碼(如 ASCII/Unicode 值),可以使用?ord()?和?chr()?函數:

python

運行

char = 'A'
code = ord(char)  # 65 (Unicode 碼點)
back_to_char = chr(code)  # 'A'

這種設計讓 Python 在處理文本時更加統一和靈活,無需擔心字符與字符串的類型轉換問題。 😊

3?生成一個PyCodeObject對象是什么意思?

在 Python 中,生成一個?PyCodeObject?對象?意味著將源代碼編譯為 Python 虛擬機(VM)可以執行的中間表示形式,也稱為?字節碼(bytecode)。這個過程是 Python 執行代碼的關鍵步驟,理解它有助于掌握 Python 的運行機制。

1. 什么是?PyCodeObject

PyCodeObject?是 CPython 解釋器(用 C 語言實現的 Python 官方解釋器)中的一個核心數據結構,它存儲了編譯后的代碼信息,包括:

  • 字節碼指令:如?LOAD_CONSTCALL_FUNCTION?等,類似于匯編語言。
  • 常量池:存儲數字、字符串等常量。
  • 局部變量信息:變量名、位置等。
  • 源代碼位置:用于調試(如錯誤堆棧跟蹤)。

可以將?PyCodeObject?看作是源代碼的?編譯產物,類似于 Java 的?.class?文件或 C 的目標文件(.o)。

2. 為什么需要?PyCodeObject

Python 是?解釋型語言,但執行前需要先將源代碼編譯為字節碼,原因如下:

  • 跨平臺性:字節碼可以在任何 Python 解釋器上運行,無需重新編譯。
  • 性能優化:編譯一次,多次執行(字節碼可以緩存,如?.pyc?文件)。
  • 簡化解釋器邏輯:解釋器只需執行字節碼,無需處理源代碼的語法解析。

3. 生成?PyCodeObject?的過程

當你運行 Python 代碼時:

  1. 詞法分析:將源代碼轉換為 token(如?defclass、變量名)。
  2. 語法分析:構建抽象語法樹(AST)。
  3. 代碼生成:將 AST 轉換為?PyCodeObject(包含字節碼)。

這個過程由 Python 解釋器自動完成,例如:

python

運行

def add(a, b):return a + b# 編譯后,add 函數對應一個 PyCodeObject,包含以下字節碼:
#   2           0 LOAD_FAST                0 (a)
#               2 LOAD_FAST                1 (b)
#               4 BINARY_ADD
#               6 RETURN_VALUE

4. 哪些代碼會生成?PyCodeObject

以下情況會生成獨立的?PyCodeObject

  • 模塊(.py?文件):每個文件有一個全局的?PyCodeObject
  • 函數定義:每個?def?語句生成一個(包括 lambda 函數)。
  • 類定義:每個?class?語句生成一個(類體中的代碼會被編譯)。
  • 生成器表達式:如?(x for x in range(10))
  • 嵌套的代碼塊:如方法、嵌套函數等。

5. 如何查看字節碼?

可以使用?dis?模塊反匯編?PyCodeObject

python

運行

import disdef add(a, b):return a + bdis.dis(add)  # 打印字節碼指令

輸出:

plaintext

  2           0 LOAD_FAST                0 (a)2 LOAD_FAST                1 (b)4 BINARY_ADD6 RETURN_VALUE

總結

生成?PyCodeObject?是 Python 執行代碼的必經之路,它將源代碼轉換為可執行的字節碼,讓 Python 兼具解釋型語言的靈活性和編譯型語言的部分性能優勢。理解這一點有助于解釋一些 Python 特性,如:

  • 為什么函數定義是運行時執行的(因為需要生成?PyCodeObject)。
  • 為什么修改源代碼后需要重新運行(除非使用?.pyc?緩存)。
  • 為什么嵌套函數可以捕獲外部變量(PyCodeObject?保存了閉包信息)。

4?Python 作用域與 PyCodeObject

題目
Python 代碼經過編譯后,一共生成多少個 PyCodeObject 對象?

python

運行

class A:pass
def Fun():pass
a = A()
Fun()

選項
A. 1
B. 2
C. 3
D. 4

你的答案
B. 2

正確答案
C. 3

🔍 錯誤原因分析

  1. 混淆作用域的定義

    • 誤將類實例化(a = A())和函數調用(Fun())視為獨立作用域。
    • 實際上,只有模塊、類定義、函數定義會創建新的作用域
  2. 對 PyCodeObject 的生成規則理解不深

    • 每個獨立作用域(名字空間)對應一個 PyCodeObject。
    • 題目中存在?3 個作用域

      python

      運行

      # 作用域1:模塊級別(全局命名空間)
      class A:        # 作用域2:類 A 的命名空間passdef Fun():      # 作用域3:函數 Fun 的命名空間passa = A()         # 全局命名空間中的語句
      Fun()           # 全局命名空間中的語句
      

📚 關鍵知識點

  1. PyCodeObject 生成規則

    結構是否生成 PyCodeObject示例
    模塊(.py?文件)?整個代碼文件
    類定義(class?class A: pass
    函數定義(def?def Fun(): pass
    實例化對象?a = A()
    函數調用?Fun()
    普通語句?賦值、條件判斷、循環等
  2. 驗證方法
    通過?__code__?屬性查看對象對應的 PyCodeObject(實際是?code?對象):

    python

    運行

    print(A.__code__)       # 類體對應的 code 對象
    print(Fun.__code__)     # 函數體對應的 code 對象
    print(__code__)         # 當前模塊對應的 code 對象
    

💡 記憶技巧

  1. 作用域劃分口訣

    模塊類函數,作用域三分;實例與調用,作用域不分

  2. 嵌套作用域示例

    python

    運行

    def outer():            # 作用域1x = 10class Inner:        # 作用域2passdef inner():        # 作用域3y = 20return inner
    

    上述代碼包含?3 個 PyCodeObjectouterInnerinner?各一個)。

📝 總結

  1. 明確作用域邊界:類、函數、模塊是作用域的核心劃分單位。
  2. 區分編譯時與運行時
    • 編譯時生成 PyCodeObject(如類 / 函數定義)。
    • 運行時執行代碼(如實例化 / 函數調用)不生成新的 PyCodeObject。

下次遇到同類題目的思考步驟

  1. 找出代碼中的模塊、類、函數定義。
  2. 統計獨立作用域的數量。
  3. 忽略實例化、函數調用等運行時操作。

5?Python中淺拷貝和深拷貝的區別,以及列表復制時的引用特性

執行以下程序,輸出結果為()
a = [['1','2'] for i in range(2)]b = [['1','2']]*2a[0][1] = '3'b[0][0] = '4'print(a,b) A [['1', '3'], ['1', '3']] [['4', '2'], ['4', '2']]B [['1', '3'], ['1', '2']] [['4', '2'], ['4', '2']]C [['1', '3'], ['1', '2']] [['4', '2'], ['1', '2']]D [['1', '3'], ['1', '3']] [['4', '2'], ['1', '2']]答案:B

1. 列表初始化方式對比

方式語法示例對象關系內存特性
列表推導式a = [['1','2'] for _ in range(2)]創建多個獨立對象子列表內存地址不同
乘法操作b = [['1','2']] * 2復制同一對象的引用子列表內存地址相同

2. 淺拷貝與深拷貝的區別

  • 淺拷貝
    僅復制容器(如列表)本身,內部元素仍為原對象的引用。
    示例b = [['1','2']] * 2?中,子列表?['1','2']?被重復引用。

  • 深拷貝
    遞歸復制容器及其所有嵌套對象,生成完全獨立的新對象。
    實現方式:使用?copy.deepcopy()?函數。

3. 引用特性導致的修改行為差異

  • 獨立對象(列表推導式)
    修改任一子列表僅影響當前對象。
    示例a[0][1] = '3'?僅修改?a[0]

  • 共享引用(乘法操作)
    修改任一子列表會影響所有引用同一對象的元素。
    示例b[0][0] = '4'?同時修改?b[0]?和?b[1]

4. 驗證對象身份的方法

使用?id()?函數檢查內存地址:

python

運行

a = [['1','2'] for _ in range(2)]
b = [['1','2']] * 2
print(id(a[0]) == id(a[1]))  # False(獨立對象)
print(id(b[0]) == id(b[1]))  # True(共享引用)

5. 實際應用中的注意事項

  • 多維數組初始化
    初始化多維列表時,避免使用?[[val]*n]*m(如?[[0]*3]*3),應使用列表推導式?[[val for _ in range(n)] for _ in range(m)]

  • 數據處理場景
    在需要獨立操作子元素的場景(如矩陣運算、數據分組)中,確保使用獨立對象初始化。

6. 總結

  • 列表推導式適合創建獨立的嵌套結構。
  • 乘法操作僅復制引用,適用于不可變元素(如整數、字符串),但不適合嵌套可變對象(如列表)。
  • 使用?id()?或?is?操作符驗證對象身份,避免因引用共享導致的意外修改。

為了更直觀地驗證這一行為,我們可以通過以下代碼檢查對象的內存地址

python

運行

a = [['1','2'] for i in range(2)]
b = [['1','2']]*2print(f"a[0] 地址: {id(a[0])}")  # 不同地址
print(f"a[1] 地址: {id(a[1])}")print(f"b[0] 地址: {id(b[0])}")  # 相同地址
print(f"b[1] 地址: {id(b[1])}")a[0][1] = '3'
b[0][0] = '4'print("修改后 a:", a)
print("修改后 b:", b)

輸出結果:

plaintext

a[0] 地址: 140281423443648
a[1] 地址: 140281423443904
b[0] 地址: 140281423443776
b[1] 地址: 140281423443776
修改后 a: [['1', '3'], ['1', '2']]
修改后 b: [['4', '2'], ['4', '2']]

關鍵點:

  1. 列表推導式創建獨立對象a?的子列表內存地址不同,說明它們是獨立的對象。
  2. 乘法操作復制引用b?的子列表內存地址相同,說明它們指向同一個對象。
  3. 修改行為驗證:對?b?的任一子列表的修改會反映到所有引用中,而?a?的子列表相互獨立。

這一特性在處理嵌套數據結構時尤為重要,例如矩陣操作或多維數組的初始化。理解引用機制可以避免潛在的邏輯錯誤。

理解這些特性可以有效避免 Python 中常見的引用陷阱,提升代碼的健壯性。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/90277.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/90277.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/90277.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux 環境下安裝 MySQL 8.0.34 二進制 詳細教程 附docker+k8s啟動

文章目錄Linux 環境下安裝 MySQL 8.0&#xff08;二進制&#xff09;詳細教程準備工作安裝依賴包下載并解壓 MySQL下載 MySQL 二進制包解壓 MySQL移動目錄并創建 MySQL 用戶配置 MySQL配置數據目錄與日志目錄編輯配置文件 /etc/my.cnf初始化 MySQL 數據庫配置啟動腳本與環境變量…

HTML ISO-8859-1: 完全解析

HTML ISO-8859-1: 完全解析 引言 ISO-8859-1,又稱為 Latin-1,是一種廣泛使用的字符編碼標準,特別是在HTML文檔中。本文將詳細介紹ISO-8859-1編碼的特點、應用場景以及如何在使用HTML時正確地使用ISO-8859-1編碼。 ISO-8859-1編碼概述 定義 ISO-8859-1編碼是一種單字節編…

c++學習第3篇編輯器——centos7.9.2009系統離線安裝clion軟件并成功調試c++程序

遠程linux服務器安裝clion0 前提2個&#xff1a;1 下載CLion-2021.1.1.tar.gz安裝包2 上傳到linux系統并解壓3 修改linux系統里的/etc/ssh/sshd_config文件中的X11UseLocalhost 注釋去掉并設為no4 安裝xauth5 安裝MobaXterm軟件并使用ssh組件打開clion5.1 如果打不開clion,報錯…

20250722解決在Ubuntu 24.04.2下編譯RD-RK3588開發板的Android13出現找不到lz4的問題

20250722解決在Ubuntu 24.04.2下編譯RD-RK3588開發板的Android13出現找不到lz4的問題 2025/7/22 15:21緣起&#xff1a;在Ubuntu 24.04.2下編譯RD-RK3588開發板的Android13。 報錯&#xff1a;/bin/sh: 1: lz4: not found為了簡單起見&#xff0c;直接在 榮品的技術支持QQ群的 …

加載用戶設置時遇到錯誤找到一個帶有無效“icon“的配置文件。將該配置文件默認為無圖標。確保設置“icon“時,該值是圖像的有效文件路徑“

"C:\Users\Yourname\AppData\Local\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json 修改所有icon字段位none 如&#xff1a;{"guid": "{bf61c995-08cc-4a56-b781-5dba411ef19c}","hidden": false,"icon&…

如何提升連帶消費?從新零售“人-貨-場”模型拆解

目錄 一、分析背景 二、新零售分析思路和分析方法 1.具體分析思路 2.分析方法 三、新零售“人-貨-場”分析的實操步驟 1.數據收集 2.數據處理 3.圖表制作 四、總結 想讓線上引來的顧客&#xff0c;在店里多買幾件&#xff1f; 連帶消費可是實體店賺錢的“秘密武器”&a…

Java異常處理核心原理與最佳實踐

Java異常處理核心原理與最佳實踐 場景&#xff1a; 你開發的文件處理工具在讀取用戶上傳的文件時突然崩潰&#xff0c;控制臺拋出FileNotFoundException。用戶的操作被中斷&#xff0c;數據丟失。這種糟糕的體驗正是異常處理機制要解決的核心問題——如何在程序出錯時優雅地恢復…

Ubuntu 安裝 Odoo 17 詳細教程

Ubuntu 安裝 Odoo 17 詳細教程 本教程將指導您在 Ubuntu 系統上從源代碼安裝 Odoo 17。Odoo 是一款功能強大的開源 ERP 和 CRM 軟件套件。本教程適用于希望自行配置和管理 Odoo 環境的用戶&#xff0c;尤其適合開發者和系統管理員。 教程概述 本教程將涵蓋以下步驟&#xff…

鯤鵬·卓識系列2.45G傳感器型有源標簽:以國產化技術重塑安全監測與人員管理新標準

標題&#xff1a;鯤鵬卓識系列2.45G傳感器型有源標簽&#xff1a;以國產化技術重塑安全監測與人員管理新標準 隨著工業4.0和智慧城市建設的加速推進&#xff0c;安全生產、環境監測和人員管理成為各行業的核心需求。在軍事、工業、倉儲、能源等領域&#xff0c;溫濕度、煙霧、油…

騰訊云推出CodeBuddy:革新AI全棧開發體驗

文章目錄一、前言二、安裝流程三、CodeBuddy 核心功能3.1 AI輔助開發3.2 Coding Design Chat 三大模式3.3 Boost Prompt3.4 Figma 集成3.5 Componen 控件庫3.6 Config MCP3.7 Upload Images 圖片上傳和管理3.8 Preview功能3.9 Deploy 一鍵部署3.10 項目展示 | MCP生成小紅書卡片…

龍虎榜——20250723

上證指數放量收上影線&#xff0c;未站上3600點&#xff0c;個股下跌明顯多于上漲&#xff0c;指數有調整需求&#xff0c;注意短線風險。深證指數較昨日縮量收陰線&#xff0c;依然在5日均線上方運行&#xff0c;打到前期平臺高點有震蕩調整需求&#xff0c;注意風險。2025年7…

SpringBoot06-@ConfigurationProperties注解

ConfigurationProperties注解用于將配置文件&#xff08;application.properties 或 application.yml&#xff09;中的配置值&#xff0c;自動綁定到 Java Bean 對象上。1-1、基本用途比如我們在 application.yml 中有這樣一段配置&#xff1a;app:name: myAppversion: 1.0.0au…

oracle里面concat函數用法,oracle wm_concat函數用法-

wmsys.wm_concat函數&#xff0c;它的作用是以’,’鏈接字符 例子如下&#xff1a; SQL> create table idtable (id number,name varchar2(30)); Table created SQL> insert into idtable values(10,’ab’); 1 row inserted SQL> insert into idtable values(10,’bc…

C++中的list(2)簡單復現list中的關鍵邏輯

C中的list&#xff08;2&#xff09;//簡單復現list中的關鍵邏輯 前言 這一節的主要內容就是&#xff1a;簡單復現list中的關鍵邏輯。同樣的&#xff0c;我們這一節也是先粗略的看一眼源碼&#xff0c;結合源碼&#xff0c;邊理解邊復現。源碼我已經上傳到gitee&#xff0c;網…

Linux——System V 共享內存 IPC

文章目錄一、共享內存的原理二、信道的建立1.創建共享內存1.key的作用2.key的選取3.shmid的作用4.key和shmid的區別5.內存設定的特性6.shmflg的設定2.綁定共享內存3.代碼示例三、利用共享內存通信1.通信2.解除綁定3.銷毀共享內存1.命令行銷毀2.程序中銷毀四、共享內存的生命周期…

Python 程序設計講義(9):Python 的基本數據類型——復數

Python 程序設計講義&#xff08;9&#xff09;&#xff1a;Python 的基本數據類型——復數 復數與數學中的復數概念類似。在 Python 中&#xff0c;復數表示為 abj&#xff0c;其中&#xff1a;a為實數部分&#xff0c;b為虛數部分&#xff0c;j稱為虛數單位。復數必須包含虛數…

leetcode_121 買賣股票的最佳時期

1. 題意 有一個股價變化圖&#xff0c;你可以在一天買入&#xff0c;在未來一天賣出。 求通過這樣一次操作的最大獲利。 2. 題解 2.1 枚舉 直接枚舉&#xff0c;買入賣出的時間&#xff0c;肯定會超時啦~ 時間復雜度為O(n2)O(n^2)O(n2) 空間復雜度為O(1)O(1)O(1) class …

ToBToC的定義與區別

B 端和 C 端主要是從產品所面向的用戶群體角度來區分的&#xff0c;B 端指的是企業用戶&#xff08;Business&#xff09;&#xff0c;C 端指的是個人消費者&#xff08;Consumer&#xff09;&#xff0c;它們在多個方面存在明顯區別&#xff0c;具體如下&#xff1a;用戶特征B…

Python 程序設計講義(8):Python 的基本數據類型——浮點數

Python 程序設計講義&#xff08;8&#xff09;&#xff1a;Python 的基本數據類型——浮點數 目錄Python 程序設計講義&#xff08;8&#xff09;&#xff1a;Python 的基本數據類型——浮點數一、浮點數的表示形式1、小數形式2、指數形式二、浮點數的精確度浮點數也稱小數&am…

MCP客戶端架構與實施

前言:從模型到生產力 — MCP的戰略價值 在過去的一年里,我們團隊見證了大型語言模型(LLM)從技術奇跡向企業核心生產力工具的演變。然而,一個孤立的LLM無法解決實際的業務問題。真正的價值釋放,源于將模型的認知能力與企業現有的數據、API及工作流進行無縫、安全、可擴展…