(int(digit) ** 2 for digit in str(n))
這個不是 數組(list),而是一個 生成器表達式 (generator expression)。
它的作用是:
str(n)
把數字n
轉成字符串,例如n = 82
→"82"
。for digit in str(n)
遍歷字符串中的每個字符 →"8"
,"2"
。int(digit)
把字符轉回數字 →8
,2
。** 2
表示平方 →64
,4
。所以,
(int(digit) ** 2 for digit in str(n))
生成的是一個 按需計算的序列(生成器),不會一次性把所有結果存儲下來。
但是在代碼里寫的是:
n = sum(int(digit) ** 2 for digit in str(n))
這里 sum(...)
會 遍歷生成器,把里面的每一項加起來,得到一個整數。
🔎 舉例:
如果 n = 82
:
str(n)
→"82"
遍歷
"8"
,"2"
平方得到
64
,4
sum(...)
→64 + 4 = 68
所以,結果是 68
。
👉 如果你真的想看到“像數組一樣的結果”,可以寫成 列表推導式:
[int(digit) ** 2 for digit in str(n)]
這就會直接生成一個列表,比如:
n = 82
print([int(digit) ** 2 for digit in str(n)])
# 輸出: [64, 4]
要不要我幫你把這段快樂數代碼改寫成“中間過程都打印出來”的版本?這樣你能清楚看到每次 n
的分解結果和平方和的變化。
——【list(生成器)和[生成器]的區別】—
我們一步步分析你的例子:
squares = (x ** 2 for x in range(5)) # 這是一個生成器(generator)
M = [squares] # 用 [] 包裹
1?? squares = (x ** 2 for x in range(5))
這里用 小括號
()
創建了一個 生成器(generator)。它本身 不是列表,而是可以按需生成元素的迭代器。
例如:
print(squares) # <generator object <genexpr> at 0x...>
2?? M = [squares]
這里用 列表字面量
[]
包裹了squares
。M
是一個 列表,長度為 1,里面的唯一元素就是squares
生成器對象。
print(M) # [<generator object <genexpr> at 0x...>]
print(type(M)) # <class 'list'>
注意:列表里面的元素仍然是生成器本身,不是生成器產生的數字。
3?? 如果用 list(squares)
:
squares = (x ** 2 for x in range(5))
M2 = list(squares)
print(M2) # [0, 1, 4, 9, 16]
print(type(M2)) # <class 'list'>
list()
會 遍歷生成器,把生成的每個值收集成一個列表。結果是長度 5 的列表
[0,1,4,9,16]
,而不是長度 1 的列表。
? 總結:
寫法 | 結果類型 | 內容 |
---|---|---|
[squares] | list | 列表里只有生成器對象本身 |
list(squares) | list | 列表里是生成器生成的所有值 |