355. Python 篇二:变量、字符串、列表、元组与字典

2026.08.04

·python

以 JavaScript / TypeScript 为参照,“重学”并“精通” Python。

这篇回到更底层的语言零件:变量字符串列表元组字典、条件和循环。

变量、字符串、数字、注释

变量就是名字贴到对象上

Python 没有 const / let / var。写成:

python
name = "hello world"
count = 1

对照 TS:

ts
let name = "hello world"
let count = 1

a = b 通常是让两个名字指向同一个对象,不是自动深拷贝一份。

字符串:最常用的是 f-string

python
first_name = "ada"
last_name = "lovelace"
full_name = f"{first_name} {last_name}"
print(full_name)  # ada lovelace

对照 JS 模板字符串:

ts
const fullName = `${firstName} ${lastName}`

f 就是 format

大小写转换也常见:

python
name = "hello world"
name.title()  # Hello World
name.upper()  # HELLO WORLD
name.lower()  # hello world

去空白、去前后缀:

python
" python ".strip()                 # "python"
"https://www.baidu.com".removeprefix("https://")  # "www.baidu.com"
"https://www.baidu.com".removesuffix(".com")      # "https://www.baidu"

换行和制表:

python
print("Languages:\n\tPython\n\tC\n\tJavaScript")

\n 换行,\t 缩进。和 JS 一样。

数字:下划线只是给人看的

python
large_num = 14_000_000_000
print(large_num)  # 14000000000

下划线不改变数值,只是方便读大数。和 JS 的 14_000_000_000 一样。

多变量一起赋值:

python
x, y, z = 0, 0, 0

“常量”只是约定

python
MAX_NUM = 1000

Python 没有常量关键字。全大写只是告诉人:别改这个。 但运行时照样能改,只是不该改

注释和文档字符串

单行:

python
# 这是注释

多行常见两种:

python
"""
多行说明
"""

函数里的三引号,常常当文档字符串用:

python
def greet(name: str) -> str:
    """打招呼,返回问候语。"""
    return f"Hello, {name}!"

对照:

  • JS 的 ///* */
  • TS / JSDoc 的函数说明

Python 更常把说明写进函数体开头的三引号里,工具和帮助信息会读它。

列表:可变数组

基本操作

python
arr = [1, 2, 3, 4, 5]
len(arr)       # 5
arr[2] = 30    # 改第 3 个
arr.append(6)  # 末尾追加
arr.insert(2, 7)  # 在索引 2 插入
arr.pop()      # 弹出最后一个
arr.pop(0)     # 弹出索引 0
arr.remove(2)  # 按值删第一个匹配项
del arr[2]     # 按索引删

对照 JS:

你想做的事JavaScriptPython
长度arr.lengthlen(arr)
末尾追加arr.push(x)arr.append(x)
弹出末尾arr.pop()arr.pop()
按索引删arr.splice(i, 1)del arr[i] / arr.pop(i)
按值删自己找 index 再 splicearr.remove(x)
中间插入arr.splice(i, 0, x)arr.insert(i, x)

一句话:

Python 的 list,就是你脑子里的可变数组
名字不叫 array,行为很像 JS 的 Array

拼接:

python
arr3 = arr + [9, 10, 11]

排序和反转

python
arr.sort()                 # 原地升序
arr.sort(reverse=True)     # 原地降序
sorted(arr)                # 返回新列表,不改原列表
arr.reverse()              # 原地反转

要记住一对:

  • arr.sort():改自己,返回 None
  • sorted(arr):不改自己,返回新列表

JS 也有类似坑:arr.sort() 会改原数组;需要新数组时用 [...arr].sort()toSorted()

遍历、range、统计

python
for i in arr:
    print(i)

for i in range(0, 10):
    print(i)  # 0 到 9,不含 10

list(range(0, 10))  # [0, 1, 2, ..., 9]

max(arr)
min(arr)
sum(arr)

range(0, 10) 很像:

ts
for (let i = 0; i < 10; i++) {}

只是 Python 的终点默认不含右边界

列表推导式:Python 的高频写法

python
squares = [value ** 2 for value in range(1, 11)]
# [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

对照 JS:

ts
const squares = Array.from({ length: 10 }, (_, i) => (i + 1) ** 2)
// 或
const squares = [...Array(10)].map((_, i) => (i + 1) ** 2)

读法:

先写最终要留下的值,再写 for ... in ...
它是 Python 里非常常见的“边遍历边生成新列表”写法。

切片:取出一段,也常用来复制

python
arr = [0, 1, 2, 3, 4]
arr[0:2]  # [0, 1],含左不含右
arr[:2]   # 从头到索引 2(不含)
arr[2:]   # 从索引 2 到结尾

对照 JS 的 slice

ts
arr.slice(0, 2)
arr.slice(0, 2)
arr.slice(2)

复制列表:[:] 和直接赋值不是一回事

python
arr1 = arr[:]   # 浅拷贝,新列表
arr2 = arr      # 同一个列表,两个名字

对照 JS:

ts
const arr1 = arr.slice()   // 或 [...arr]
const arr2 = arr           // 同一引用

这里接回开头那句:

arr2 = arr 不是复制内容,只是再贴一张标签。
arr2arr 也会变。

元组:写完就不能改的列表

python
dimension = (200, 50)
print(dimension[0])  # 200

for i in dimension:
    print(i)
  • 用圆括号
  • 元素不能改、不能增删
  • 能遍历、能按索引读

对照 TS:

ts
const dimension = [200, 50] as const
// 或
const dimension: readonly [number, number] = [200, 50]

一句话:

list 是可变盒子;tuple 是装好就封条的盒子。
配置、坐标、不会改的一组值,常用元组。

只有一个元素时要写逗号:

python
# 必须要要写逗号
one = (1,)  # 元组
# 没有逗号就是数字 1
not_tuple = (1)  # 只是括号里的数字 1

条件判断、布尔、逻辑

python
if score >= 90:
    grade = "A"
elif score >= 60:
    grade = "B"
else:
    grade = "C"

对照 JS:

ts
if (score >= 90) {
  grade = "A"
} else if (score >= 60) {
  grade = "B"
} else {
  grade = "C"
}

关键差别:

JavaScriptPython
否则如果else ifelif
逻辑与 / 或 / 非&& || !and or not
块边界{}: + 缩进
真假字面量true / falseTrue / False

比较运算符两边都懂:==!=><>=<=

布尔值首字母大写

python
ok = True
empty = False

Python 也有“真值”习惯:

python
items = []
if items:       # 空列表为假
    ...
if not items:   # 没有元素
    ...

空列表、空字典、空字符串、0None 在条件里都偏“假”。
这和 JS 的 truthy / falsy 很像,但具体集合不完全相同;写业务时,能显式判断就显式判断。

字典:像对象,也像 Map

python
favorite = {
    "name": "zhangsan",
    "age": 18,
}

对照 JS:

ts
const favorite = {
  name: "zhangsan",
  age: 18,
}

读取、修改、删除:

python
favorite["name"]
favorite["age"] = 19
# del
del favorite["age"]

遍历时,Python 比 JS 对象更常把键值拆开写:

python
for key, value in favorite.items():
    print(key, value)

for key in favorite.keys():
    print(key)

for value in favorite.values():
    print(value)

对照:

ts
for (const [key, value] of Object.entries(favorite)) {}
for (const key of Object.keys(favorite)) {}
for (const value of Object.values(favorite)) {}

一句话:

Python 的 dict,就是“键到值”的映射。
在 FastAPI / JSON 场景里,它几乎就是你脑子里的普通对象;只是键不一定是字符串,值可以是任意对象

字典可以嵌套:

python
payload = {
    "user": {"id": 1, "name": "ada"},
    "tags": ["python", "fastapi"],
}

这正是后面 Pydantic Model、请求体、响应 JSON 的日常形状。

取值时两个常见写法:

python
favorite["name"]          # 没有 key 会报 KeyError
favorite.get("name")      # 没有 key 返回 None
favorite.get("name", "")  # 没有 key 返回默认值

对照 JS:

ts
favorite.name
favorite.name ?? ""

用户输入:本地脚本才常用

python
message = input("请输入内容:")
print("你输入的是:", message)

input() 返回的永远是字符串。要当数字用,自己转:

python
age = int(input("年龄:"))

在 FastAPI 服务里,参数通常来自 Path / Query / Body,很少直接用 input()
它属于本地脚本、命令行小工具的基础零件;

while 循环

基本形态

python
n = 1
while n <= 5:
    print(n)
    n += 1

对照 JS:

ts
let n = 1
while (n <= 5) {
  console.log(n)
  n += 1
}

break 跳出,continue 跳过本轮,两边都一样。

注意 continue 时别忘了推进循环变量,否则容易死循环:

python
j = 1
while j <= 5:
    if j == 3:
        j += 1
        continue
    print(j)
    j += 1

while arr::直到清空

python
arr = [1, 2, 3, 4, 5]
while arr:
    cur = arr.pop()
    print(cur)
# 5 4 3 2 1

这是利用“空列表为假”的写法:有元素就继续,弹完为止。

处理队列、消化待办列表时很常见。

  • 多数 Web 接口代码更常写 for
  • while 留给“不知道要转几圈,但知道停条件”的场景。

一张总对照表

概念JavaScript / TypeScriptPython
变量let / const直接 name = ...
字符串插值`${x}`f"{x}"
数组Arraylist
不可变一组值as const / readonly tupletuple
对象映射object / Mapdict
长度.lengthlen(x)
否则如果else ifelif
逻辑运算&& || !and or not
真假true / falseTrue / False
代码块{}: + 缩进
生成新列表map / filter列表推导式
切片slicearr[a:b]
同引用赋值b = ab = a
浅拷贝数组[...a] / a.slice()a[:]

补充

注释与文档字符串

  • Python 的注释只有 #
  • 三引号创建字符串,放在模块、类或函数开头时才是文档字符串
python
# 这是注释
text = """这是多行字符串"""

# 函数体开头的三引号字符串是文档字符串
def greet():
    """这是函数的文档字符串。"""

==is

== 比较值,is 比较是否为同一个对象;is 最常用于 is None

python
a = [1]
b = [1]
c = a

# 值相同,所以是 True
print(a == b)
# 不是同一个对象,所以是 False
print(a is b)
# 是同一个对象,所以是 True
print(a is c)

value = None
# value 就是 None,所以是 True
print(value is None)

原地修改与返回值

listdict 可变,原地修改方法通常返回 Nonestr 不可变,字符串方法返回新字符串。

python
items = [3, 1]
result = items.sort()

# 原列表已经变成 [1, 3]
print(items)
# sort() 原地修改列表,返回 None
print(result)

name = "python"
# 返回新字符串 PYTHON
print(name.upper())
# 原字符串仍然是 python
print(name)

不要写 items = items.append(x),否则 items 会变成 None

浅拷贝与元组

[:] 只复制外层;元组的元素不能替换,但元组里的可变对象仍然能改。

python
original = [{"done": False}]
copied = original[:]
copied[0]["done"] = True

# 内层字典仍然共享,所以原列表中的值也是 True
print(original[0]["done"])

task = ("学习", [])
task[1].append("Python")
# 元组中的列表可以修改
print(task)

# 下面会报 TypeError,因为不能替换元组元素
# task[1] = []

需要递归复制嵌套对象时,再用 copy.deepcopy()

假值与字典

0、空字符串、空容器和 None 都是假值;判断“没传”用 is None

python
limit = 0
# 0 是假值
print(bool(limit))

payload = {"name": None}
# 键存在,值是 None
print(payload.get("name"))
# 键不存在,也返回 None
print(payload.get("age"))
# name 键存在
print("name" in payload)
# age 键不存在
print("age" in payload)

Python 的空列表、空字典是假值,JS 中则是真值。字典键必须可哈希,listdict 不能做键。

参考