动态

详情 返回 返回

Python/JS/Go/Java同步學習(第二十四篇)四語言“元組概念“對照表

🤝 免罵聲明:
  • 本文元組概念操作經本蜀黎實戰整理,旨在提供快速參考指南📝
  • 因各語言版本迭代及不同系統環境差異,偶爾可能出現整理不全面之處,實屬正常✅
  • 歡迎理性交流補充,噴子勿噴——畢竟你行你上來寫,我敬你是條漢子,告訴我的你原文鏈接,我給你一鍵三連+轉發👍!
  • 若遇具體問題,請帶圖評論區留言,本蜀黎必拔碼相助🤝
    土味海報

📜【元組專題特別説明】

⚡ 虎山CTO戰略部署:
  • 元組概念,僅此一篇,後續章節,不再重現!」🙏

🎯 學習重點定位:

  • 本次專題:徹底講透元組核心概念、不可變性價值、四語言實現差異🌈
  • 後續章節:不再單獨講解元組操作,全部默認您已掌握本篇章內容✅
  • 操作參考:元組的所有使用技巧(切片、遍歷、查找等)全部參照列表章節🔍

📚 系列課程規劃:

# 本系列技術路線圖✨
當前章節:元組概念篇(一次性深度講解)
後續路線:字典 → 集合 → 函數 → 120+面向對象(打好基礎不要過早引入封裝)...
元組出場:僅在需要不可變數據時作為"工具"出現
⚠️ 學習預警:
  • 「錯過今日,再無元組專場!請集中精力消化不可變性精髓!」💪
🌿【虎山CTO·藥材使用警示】
  • 🍀是藥三分毒,代碼亦如方!
  • ❌文中所涉藥材均為技術隱喻,嚴禁實際配伍使用。
  • 🙏真實用藥請遵醫囑,亂用者——
  • 系統崩壞事小,氣血逆流事大!⚠️
📚 系列文章預告:
  • 近期內容將聚焦編程基礎構建,以「原創知識矩陣」形式系統梳理核心概念。每篇如連續劇集般環環相扣,建議按順序學習——知識點一鍋端,療效更持久!🔥

🧠【場景還原:元組——不可篡改的聖旨】

⚡ 雷影老闆(舉起鍍金賬本重重砸向桌面):
  • 「財務三表、税率規則、會計科目——這些核心數據誰敢改一個數字,直接祭出“雷遁·數據粉碎之術”!」💎
🦊 鳴人(抓狂地翻着可變賬本):
  • 「伊魯卡老師!為什麼Python的元組像刻在石碑上,而JS/Go/Java非要折騰Object.freezefinal?我的賬本又被佐助惡意篡改了!」💎
👨‍🏫 伊魯卡(一粉筆頭命中鳴人額頭):
  • 笨蛋!元組是財務部的聖旨列表只是草稿紙🙏
  • 元組創建即封印→ 玉璽蓋印,不可篡改📌
  • 列表隨意增刪→ 鉛筆寫字,隨便擦改🌀
🐯 卡卡西(從《親熱天堂》後抬眼):
  • 「嘖...連數據 immutable 都搞不懂,以後怎麼學區塊鏈哈希防篡改之術?」
特性 元組(聖旨) 列表(草稿紙)
可變性 ❌ 創建後不可變(immutable) ✅ 可隨意增刪改(mutable)
- 元組一旦創建,其元素不可修改、添加或刪除 - 列表支持 append()remove()insert() 等方法隨時修改內容
- 適合表示不應被更改的數據,如座標、配置項 - 適合表示動態變化的集合,如用户輸入、實時數據流
內存優化 ✅ 更輕量,緩存友好 ❌ 動態擴容帶來額外開銷
- 元組結構固定,Python 會做內存優化,訪問更快 - 列表為了支持動態增長,會預留額外空間,佔用更多內存
- 小數據量時差距不明顯,大數據量時性能差異顯著 - 頻繁增刪時可能觸發多次內存重新分配
語義意圖 ✅ 表示固定結構的數據(如座標、日期、配置) ✅ 表示動態集合或臨時數據(如待辦事項、日誌、緩衝區)
- 比如:(x, y) 座標、RGB 顏色值、數據庫查詢結果的不可變行 - 比如:購物車商品列表、用户輸入的多條記錄、動態生成的序列
哈希性 ✅ 可哈希(如果元素全部可哈希,則元組本身可哈希) ❌ 不可哈希(因可變,不能作為 dict 的 key)
- 因此元組可作為 字典的鍵(dict key) - 列表不能作為字典的鍵,也不能放入集合(set)中
- 例如:d = {(1,2): "point"} 是合法的 - 例如:d = {[1,2]: "value"} 會報錯
遍歷效率 ✅ 與列表幾乎一致,有時稍快(因不可變優化) ✅ 遍歷本身效率高,但可能因擴容有額外開銷
函數傳參 ✅ 更安全(防止意外修改) ❌ 傳入函數後可能被內部修改(除非拷貝)
線程安全 ✅ 不可變,天然線程安全 ❌ 可變,多線程操作需加鎖保護
🌍 四語言元組生存現狀:
  • Python:原生支持,真·元組 (1,2,3)🏆
  • JavaScript:用 Object.freeze() 模擬,但只能淺凍結🥇
  • Go:無原生元組,用切片+接口模擬,實為“偽君子”🥈
  • Java:用 final List 模擬,但需開發者自覺不修改🥉
🐍【Python元組:正統不可變之道】
# ==================== 財務元組模塊 ====================
税率表 = (0.06, 0.09, 0.13)  # 聖旨已下,不得篡改
會計科目 = ("資產", "負債", "權益")  # 財務三表鐵三角

# ❌ 敢篡改?殺無赦!
# 税率表[0] = 0.08  # TypeError: 'tuple' object does not support item assignment

# ✅ 但元組內的可變對象仍可修改(聖旨卷軸裏的附件可更新)
混合元組 = (1, 2, ["現金", "存款"])
混合元組[2].append("應收賬款")  # ✅ 列表可變
print(混合元組)  # (1, 2, ['現金', '存款', '應收賬款'])
Python元組精髓:
  • 真·不可變:直接阻止修改企圖🥇
  • 內存優勢:比列表更節省空間🥈
  • 解構賦值:a, b, c = (1, 2, 3) 一氣呵成🥉

⚡【其他語言模擬元組:戴着鐐銬跳舞】

🔷 JavaScript:Object.freeze() 淺凍結
// ==================== 中藥常量模塊 ====================
const 十八反藥組 = Object.freeze(["甘草", "甘遂", "海藻"]); // 老祖宗的規矩

// ❌ 表面凍結,實則...
// 十八反藥組[0] = "人蔘"; // 嚴格模式下報錯

// ✅ 但嵌套對象仍可篡改!
const 複雜藥方 = Object.freeze([1, 2, ["君藥", "臣藥"]]);
複雜藥方[2].push("佐藥"); // ✅ 嵌套數組仍可變
console.log(複雜藥方); // [1, 2, ["君藥", "臣藥", "佐藥"]]

🔶 Go:切片+接口的"偽元組"

// ==================== 倉儲編碼模塊 ====================
倉庫區位碼 := []interface{}{"A區", "B區", 101} // 假裝是元組

// ❌ Go根本沒有元組,切片天生可變!
倉庫區位碼[0] = "C區" // ✅ 隨便改!

// 所謂"模擬"全靠自覺...

☕ Java:final List 的道德約束

// ==================== ERP配置模塊 ====================
final List<Object> 系統參數 = Arrays.asList("服務器IP", 8080, true);

// ❌ final只保證引用不變,內容隨便改!
// 系統參數 = new ArrayList<>(); // ❌ 引用不能變
系統參數.set(0, "新IP"); // ✅ 內容可以改!Java的"元組"是皇帝的新衣
特性 Python JavaScript Go Java
原生支持 (1, 2, 3) ❌ 模擬 ❌ 模擬 ❌ 模擬
真正不可變 ✅ 編譯級保護 ⚠️ 淺凍結(shallow frozen) ❌ 完全可變 ❌ 完全可變
內存優勢 ✅ 輕量,緩存友好 ❌ 數組包裝(模擬元組) ❌ 切片仍有開銷 ❌ 對象開銷(無原生元組)
嵌套對象保護 ❌ 內部可變對象仍可修改 ❌ 淺凍結漏洞(內部可變泄露) ❌ 完全可變 ❌ 完全可變
語義清晰度 ✅ 一看就是元組(語法明確) ⚠️ 需註釋或約定説明 ❌ 完全是切片(無特殊語義) ⚠️ 需 final 修飾(仍不安全)

⚠️【避坑指南:元組界的"藥性相沖"】

🐍 Python:嵌套列表這個後門
聖旨 = (1, 2, ["可修改內容"])
聖旨[2].append("漏洞!")  # ✅ 元組內的列表仍可變
# 解決方案:用`tuple(deepcopy(x))`真正凍結

⚡ JavaScript:嚴格模式才報錯

const 元組 = Object.freeze([1, 2, 3]);
元組[0] = 999; // 非嚴格模式下靜默失敗!
// 解決方案:始終使用"use strict"

☕ Java:final的虛假安全

final List<String> 元組 = Arrays.asList("A", "B");
元組.set(0, "C"); // 編譯通過!運行成功!
// 解決方案:用Collections.unmodifiableList()

🔶 Go:根本沒有元組概念

// Go設計哲學:不需要元組,切片夠用了
// 這反而是一種"誠實的可變"

🧪【實戰場景:財務系統常量定義】

Python(真·元組實戰):
# 財務系統核心常量
税率表 = (0.06, 0.09, 0.13)  # 增值税税率
會計期間 = ("月度", "季度", "年度")
貨幣單位 = ("CNY", "USD", "EUR")

# 安全遍歷
for 税率 in 税率表:
    print(f"當前税率:{税率}")

# 解構賦值
小規模納税人税率, 一般納税人税率, _ = 税率表
其他語言(模擬的艱辛):
// JavaScript
const 税率表 = Object.freeze([0.06, 0.09, 0.13]);
税率表.forEach(税率 => console.log(`當前税率:${税率}`));
// Go:直接使用切片,承認可變性
税率表 := []float64{0.06, 0.09, 0.13}
for _, 税率 := range 税率表 {
    fmt.Printf("當前税率:%f\n", 税率)
}
// Java:用Collections.unmodifiableList()稍微靠譜點
List<Double> 税率表 = Collections.unmodifiableList(Arrays.asList(0.06, 0.09, 0.13));
税率表.forEach(税率 -> System.out.println("當前税率:" + 税率));
以下是本蜀黎整理源碼和截圖⏬
1.Python源碼
# ==================== 財務元組模塊 ====================
# 會計科目 = tuple(["資產", "負債", "權益"])  # 給財務三表上鋼印 🔒
# 税率表[1] = 0.06  # 試圖修改税率被系統關小黑屋 💀
# ⚠️ERP_冷溪虎山:元組是財務部的不可篡改聖旨

hdj = (1,2,3,"焦山楂","焦神曲","焦麥芽",[10,11]) #消化藥 焦三仙 元組
hdj1 = (1,2,3,"焦山楂","焦神曲","焦麥芽") #消化藥 焦三仙 元組
hdj2 = 1,2,3,"焦山楂","焦神曲","焦麥芽" #消化藥 焦三仙 元組不帶括號

hdj_list = ["焦山楂","焦神曲","焦麥芽"] #消化藥 焦三仙 列表

print(hdj1,id(hdj1))    #內存地址一致
print(hdj1,id(hdj2))  #內存地址一致

print("\n🍜🍜🍜🍜🍜以下是元組的操作🍜🍜🍜🍜🍜")
print(tuple(hdj_list)) #列表轉元組

# hdj[0] = 99  # 報錯!TypeError: 'tuple' object does not support item assignment,不能修改
hdj[-1].append(12)  #元組裏的列表可以修改
print(hdj)

print("\n🎰🎰🎰🎰🎰元組的切片,查找,獲取元素,刪除參照之前的列表操作🎰🎰🎰🎰")

Python

2.Nodejs源碼
// ==================== 中藥常量模塊 ====================
// 十八反藥組不可修改  // 老祖宗定死的配伍禁忌 ⚠️
// 試圖調整君臣順序  // 藥王鼎自動鎖死保護 🔐
// ⚠️虎山老藥師:丹方核心要素禁止篡改

// 模擬元組(用數組 + Object.freeze 防止修改)
const hdj = Object.freeze([1, 2, 3, "焦山楂", "焦神曲", "焦麥芽", [10, 11]]); // 消化藥 焦三仙 元組
const hdj1 = Object.freeze([1, 2, 3, "焦山楂", "焦神曲", "焦麥芽"]); // 消化藥 焦三仙 元組
const hdj2 = [1, 2, 3, "焦山楂", "焦神曲", "焦麥芽"]; // 消化藥 焦三仙 元組(不帶括號)

const hdj_list = ["焦山楂", "焦神曲", "焦麥芽"]; // 消化藥 焦三仙 列表

// 打印內存地址(JavaScript 沒有真正的 id,可以用引用比較)
console.log(hdj1, hdj1 === hdj1); // true(引用相同)
console.log(hdj1, hdj2); // false(不同數組,即使內容相同)

console.log("\n🍜🍜🍜🍜🍜以下是元組的操作🍜🍜🍜🍜🍜");
// 列表轉元組(JavaScript 沒有 tuple(),直接使用數組)
const tupleFromList = [...hdj_list]; // 解構賦值(類似 Python 的 tuple(hdj_list))
console.log(tupleFromList); // ["焦山楂", "焦神曲", "焦麥芽"]

// hdj[0] = 99; // 報錯!TypeError: Cannot assign to read-only property '0' of object '[object Array]'
// 但 Object.freeze 只在嚴格模式下報錯,非嚴格模式下靜默失敗
// 所以這裏模擬不可變性(實際 JavaScript 數組仍然可變,除非用深凍結)

// 元組裏的列表可以修改(因為 Object.freeze 只凍結一層)
hdj[6].push(12); // 修改元組內的列表
console.log(hdj); // [1, 2, 3, "焦山楂", "焦神曲", "焦麥芽", [10, 11, 12]]

console.log("\n🎰🎰🎰🎰🎰元組的切片,查找,獲取元素,刪除參照之前的列表操作🎰🎰🎰🎰");
// 切片(類似 Python 的切片)
console.log(hdj.slice(1, 4)); // [2, 3, "焦山楂"]
console.log(hdj.slice(-2)); // ["焦麥芽", [10, 11, 12]]

// 查找
console.log(hdj.indexOf("焦神曲")); // 4

// 獲取元素
console.log(hdj[0]); // 1

// 刪除(JavaScript 數組沒有直接刪除元素的方法,但可以用 splice)
// hdj.splice(1, 1); // 刪除第 2 個元素(索引 1)
console.log(hdj); // [1, 3, "焦山楂", "焦神曲", "焦麥芽", [10, 11, 12]]
  

nodejs

3.Go源碼
package main

import (
    "fmt"
)

// ==================== 倉儲編碼模塊 ====================
// 倉庫區位碼永久鎖定  // 建築結構無法更改 🏗️
// 試圖修改貨架座標  // 智能系統啓動防禦 🛡️
// ⚠️冷溪物流:基礎編碼如同承重牆不可動

func main() {
    // 模擬元組(用 slice + interface{} 模擬混合類型)
    hdj := []interface{}{1, 2, 3, "焦山楂", "焦神曲", "焦麥芽", []int{10, 11}} // 消化藥 焦三仙 元組
    hdj1 := []interface{}{1, 2, 3, "焦山楂", "焦神曲", "焦麥芽"}               // 消化藥 焦三仙 元組
    hdj2 := []interface{}{1, 2, 3, "焦山楂", "焦神曲", "焦麥芽"}               // 消化藥 焦三仙 元組(不帶括號)

    hdj_list := []string{"焦山楂", "焦神曲", "焦麥芽"} // 消化藥 焦三仙 列表

    // 打印內存地址(Go 沒有 id(),可以用 & 獲取指針地址)
    fmt.Printf("%p, %p\n", &hdj1, &hdj1) // 相同地址(同一變量)
    fmt.Printf("%p, %p\n", &hdj1, &hdj2) // 不同地址

    fmt.Println("\n🍜🍜🍜🍜🍜以下是元組的操作🍜🍜🍜🍜🍜")
    // 列表轉元組(Go 沒有 tuple(),直接使用 slice)
    tupleFromList := hdj_list  // 直接賦值
    fmt.Println(tupleFromList) // [焦山楂 焦神曲 焦麥芽]

    // hdj[0] = 99; // 可以修改(Go 的 slice 是可變的)
    // 但 hdj[6] 是 []int,仍然可變
    hdj[6] = append(hdj[6].([]int), 12) // 修改元組內的切片
    fmt.Println(hdj)                    // [1 2 3 焦山楂 焦神曲 焦麥芽 [10 11 12]]

    fmt.Println("\n🎰🎰🎰🎰🎰元組的切片,查找,獲取元素,刪除參照之前的列表操作🎰🎰🎰🎰")
    // 切片(Go 的 slice 支持)
    fmt.Println(hdj[1:4])         // [2 3 焦山楂]
    fmt.Println(hdj[len(hdj)-2:]) // [焦麥芽 [10 11 12]]

    // 查找(Go 沒有 indexOf,需要手動實現)
    index := -1
    for i, v := range hdj {
        if v == "焦神曲" {
            index = i
            break
        }
    }
    fmt.Println(index) // 4

    // 獲取元素
    fmt.Println(hdj[0]) // 1

    // 刪除(Go 沒有直接刪除方法,但可以用 append + slice)
    hdj = append(hdj[:1], hdj[2:]...) // 刪除第 2 個元素
    fmt.Println(hdj)                  // [1 3 焦山楂 焦神曲 焦麥芽 [10 11 12]]
}

golang

4.Java源碼
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

// ==================== ERP配置模塊 ====================
// 系統參數組永久固化  // 刻在數據庫石碑上 𓏍
// 試圖修改審批流程  // 觸發甲骨文級加密 🔏
// ⚠️ERP老兵_冷溪虎山:核心配置如同憲法不可違

class main24 {
    public static void main(String[] args) {
        // 改用 new ArrayList<>() 包裝,使其可變
        List<Object> hdj = new ArrayList<>(Arrays.asList(1, 2, 3, "焦山楂", "焦神曲", "焦麥芽", new ArrayList<>(Arrays.asList(10, 11))));
        List<Object> hdj1 = new ArrayList<>(Arrays.asList(1, 2, 3, "焦山楂", "焦神曲", "焦麥芽"));
        List<Object> hdj2 = new ArrayList<>(Arrays.asList(1, 2, 3, "焦山楂", "焦神曲", "焦麥芽"));

        List<String> hdj_list = Arrays.asList("焦山楂", "焦神曲", "焦麥芽");

        System.out.println(hdj1 + ", " + System.identityHashCode(hdj1));
        System.out.println(hdj1 + ", " + System.identityHashCode(hdj2));

        System.out.println("\n🍜🍜🍜🍜🍜以下是元組的操作🍜🍜🍜🍜🍜");
        // 列表轉元組(直接使用 List)
        List<String> tupleFromList = new ArrayList<>(hdj_list);
        System.out.println(tupleFromList);

        // 修改元組內的列表(現在可以修改了)
        ((List<Integer>) hdj.get(6)).add(12);
        System.out.println(hdj); // [1, 2, 3, 焦山楂, 焦神曲, 焦麥芽, [10, 11, 12]]

        System.out.println("\n🎰🎰🎰🎰🎰元組的切片,查找,獲取元素,刪除參照之前的列表操作🎰🎰🎰🎰");
        System.out.println(hdj.subList(1, 4)); // [2, 3, 焦山楂]
        System.out.println(hdj.subList(hdj.size() - 2, hdj.size())); // [焦麥芽, [10, 11, 12]]

        System.out.println(hdj.indexOf("焦神曲")); // 4
        System.out.println(hdj.get(0)); // 1

        // 刪除(現在可以刪除了)
        List<Object> mutableHdj = new ArrayList<>(hdj);
        mutableHdj.remove(1); // 刪除第 2 個元素
        System.out.println(mutableHdj); // [1, 3, 焦山楂, 焦神曲, 焦麥芽, [10, 11, 12]]
    }
}
 

Java

源碼分享結束⏫

📜【結局:數據不可變性的勝利】

⚡ 雷影老闆(看着審計報告滿意點頭):
  • 「這才是真正的財務安全!元組如磐石,列表如流水——從今天起,核心配置全部使用元組封裝!」✨
🌸 雛田(小聲對鳴人説):
  • 「鳴人...元組就像結婚誓言...一旦承諾就...就不能更改了呢...💕」
🦊 鳴人(恍然大悟):
  • 「原來如此!重要數據元組日常操作列表——這就是影分身之術與本體的關係🌈」
🐯 卡卡西(終於合上《親熱天堂》):
  • 「嗯...總算理解了immutable的重要性。下次教你們用元組實現數據庫事務回滾...🚀」
💥 佐助(寫輪眼洞察一切):
  • 「哼...吊車尾的,等你能用Go實現真·不可變元組再説吧💥」

🏆【四語言元組心法口訣】

Python:
  • 真元組,不可變,內存小,效率高📌
  • 嵌套列表是漏洞,深凍結才能保安全✅
JavaScript:
  • Object.freeze模擬,嚴格模式才報錯😱
  • 淺凍結如紙老虎,嵌套對象隨便改😭
Go:
  • 無元組,不假裝,切片可變是特色👊
  • 要安全,靠自覺,代碼規範大於天🧱
Java:
  • final引用不變,內容照樣可以改🔮
  • 如需真不可變,Collections.unmodifiableList🏆
🔥 記憶口訣:
  • 元組如聖旨,列表如草稿🏆
  • Python真支持,其他靠模擬🥇
  • 不可變是福,可變性是禍🥈
  • 選對數據結構,代碼百年穩固🥉

⚠️ 免責聲明(附因果律警告)

本代碼已注入中醫玄學能量,請謹慎使用:

  • ✅ 允許白嫖,但白嫖不點贊可能導致:

    • 下次面試官恰好問到這個算法
    • 鍵盤自動打出//這裏感謝冷溪虎山CTO
    • 奶茶精準灑在剛寫好的代碼上
  • ✅ 允許商用轉發,但商用不註明出處可能觸發:

    • 系統類型混亂自動轉型
    • 數據庫莫名存儲"君臣佐使"字段
  • ✅ 允許吐槽,但吐槽不帶改進建議可能引發:

    • 終生與老闆N連鞭相愛相殺

🚀 現在立即行動:

  1. 點贊 → 吸收本篇算法精華+怪蜀黎腦洞思維
  2. 收藏 → 避免日後求醫無門
  3. 關注 → 接收更多「中醫+代碼」腦洞
  4. 評論區留言 → 領取你的專屬「算法藥方」

⚠️ 友情提示:

  • 本文內容過於硬核,建議點贊收藏轉發三連,避免小編心情波動導致文章神秘消失
  • 畢竟小編今天可能愛答不理,明天可能高攀不起——
  • 但你的收藏夾,永遠是你最穩的知識備份!

    🐶💻 (小聲説:關我小黑屋?不存在的,備份早已同步GitHub/公眾號/網盤!)

📚 往期爆文推薦,VIP輪換解鎖:

📖Python/JS/Go/Java四語言同步學習,跨語言系列上線(別在糾結學什麼單語言了)

🔍 沒看過前傳?快補課!
1-18篇請移步至"PY-JS-GO-JAVA基礎進階學習系列"合集中閲讀

  • Python/JS/Go/Java同步學習(第二十三篇)四語言“列表排序|查找統計“對照表: 雷影“老闆“發飆要求員工下班留校培訓風暴(附源碼/截圖/參數表/避坑指南)
  • Python/JS/Go/Java同步學習(第二十二篇)四語言“列表刪改查|淺深拷貝“對照表: 雷影“老闆“發飆要求員工下班留校培訓風暴(附源碼/截圖/參數表/避坑指南)
  • Python/JS/Go/Java同步學習(第二十一篇)四語言“列表增改查“對照表: 雷影“老闆“發飆要求員工下班留校培訓風暴(附源碼/截圖/參數表/避坑指南)
  • Python/JS/Go/Java同步學習(第二十篇)四語言“列表遍歷“對照表: 雷影“老闆“發飆要求員工下班留校培訓風暴(附源碼/截圖/參數表/避坑指南)
  • Python/JS/Go/Java同步學習(第十九篇)四語言“列表相關操作“對照表: 雷影“老闆“發飆要求員工下班留校培訓風暴(附源碼/截圖/參數表/避坑指南)
user avatar
0 用户, 点赞了这篇动态!

发布 评论

Some HTML is okay.