【C#vsPython·第一阶段】 Python 的运算符,有些地方真的“骚“
在 C# 里判断一个数在 0 到 10 之间,你得写 x > 0 && x < 10。
在 Python 里?直接写 0 < x < 10。对,就这么简单,编译器...哦不,解释器不会报错。
当我第一次看到这个写法的时候,我心想:"这也行?"然后我试了一下,真的行。
Python 的运算符,有些地方真的"骚"。
算术运算符
C# 版本:
int a = 10, b = 3;
int sum = a + b; // 13
int diff = a - b; // 7
int product = a * b; // 30
double division = (double)a / b; // 3.333...(需要类型转换)
int intDivision = a / b; // 3(整数除法)
int remainder = a % b; // 1(取余)
// 幂运算(没有内置运算符)
double power = Math.Pow(2, 10); // 1024.0
Python 版本:
a, b = 10, 3
sum_val = a + b # 13
diff = a - b # 7
product = a * b # 30
division = a / b # 3.333...(始终是浮点数)
int_div = a // b # 3(整除)
remainder = a % b # 1(取余)
# 幂运算(内置运算符!)
power = 2 ** 10 # 1024
| 对比项 | C# | Python |
|---|---|---|
| 加法 | + |
+ |
| 减法 | - |
- |
| 乘法 | * |
* |
| 除法 | /(整数会截断) |
/(始终浮点数) |
| 整除 | / + 类型转换 |
//(专用运算符) |
| 取余 | % |
% |
| 幂运算 | Math.Pow() |
** |
C# 的 / 在整数之间会截断(10 / 3 = 3),Python 的 / 始终返回浮点数(10 / 3 = 3.333...)。要整除得用 //。
Python 的 ** 幂运算让数学公式几乎可以"原样翻译"成代码——x ** 2 就是 x 的平方,比 Math.Pow(x, 2) 简洁太多了。
为什么 Python 要这样设计?
因为 Python 的设计哲学是**"代码即数学"**。在数学中,幂运算就是上标,Python 用 ** 来表示,非常直观。而 C# 需要调用 Math.Pow() 方法,不够优雅。
真实场景:在数据分析和科学计算中,经常需要计算幂次方。Python 的 ** 运算符让代码更简洁:
# 计算圆的面积
radius = 5
area = 3.14159 * radius ** 2
# 计算复利
principal = 1000
rate = 0.05
years = 10
future_value = principal * (1 + rate) ** years
C# 得这样写:
double radius = 5;
double area = 3.14159 * Math.Pow(radius, 2);
double principal = 1000;
double rate = 0.05;
int years = 10;
double futureValue = principal * Math.Pow(1 + rate, years);
链式比较
C# 不能链式比较:
int x = 5;
// 这样写会报错
// if (0 < x < 10) { } // 编译错误
// 必须这样写
if (x > 0 && x < 10)
{
Console.WriteLine("x 在 0 到 10 之间");
}
// 多条件比较
if (x > 0 && x < 100 && x != 50)
{
Console.WriteLine("满足条件");
}
Python 支持链式比较:
x = 5
if 0 < x < 10:
print("x 在 0 到 10 之间")
# 多条件比较
if 0 < x < 100 != 50:
print("满足条件")
# 等价于
if (0 < x) and (x < 100) and (x != 50):
print("满足条件")
| 特性 | C# | Python |
|---|---|---|
| 链式比较 | 不支持 | 支持 |
| 多条件 | 用 && 连接 |
直接链式写 |
| 可读性 | 一般 | 更好 |
Python 的链式比较 0 < x < 10 是真正的"语法糖",C# 想这么写得编译器报错。
为什么 Python 要支持链式比较?
因为链式比较更符合数学直觉。在数学中,我们习惯写 0 < x < 10,而不是 x > 0 ∧ x < 10。Python 让代码更接近数学表达。
真实场景:在验证表单输入时,经常需要检查范围:
# 检查年龄是否有效
age = 25
if 0 <= age <= 150:
print("年龄有效")
else:
print("年龄无效")
C# 得这样写:
int age = 25;
if (age >= 0 && age <= 150)
{
Console.WriteLine("年龄有效");
}
else
{
Console.WriteLine("年龄无效");
}
逻辑运算符
C# 版本:
bool a = true, b = false;
bool and = a && b; // false
bool or = a || b; // true
bool not = !a; // false
// 短路求值
if (a && SomeExpensiveOperation())
{
// 如果 a 是 false,SomeExpensiveOperation() 不会执行
}
Python 版本:
a, b = True, False
and_val = a and b # False
or_val = a or b # True
not_val = not a # False
# 短路求值(和 C# 一样)
if a and some_expensive_operation():
# 如果 a 是 False,some_expensive_operation() 不会执行
pass
# 但要注意:Python 返回的是实际的值,不一定是布尔值
x = None or "default" # "default"
y = 0 or 42 # 42
z = "hello" or "world" # "hello"
Python 的 and/or 返回的是实际的值,不一定是布尔值。None or "default" 返回 "default",0 or 42 返回 42。这个特性在 C# 里是没有的。
为什么 Python 的 and/or 返回实际值?
因为 Python 的 and/or 是短路求值运算符,它们返回最后一个被求值的表达式。这个特性可以用来实现默认值:
# 设置默认值
name = user_input or "Anonymous"
等价于:
if user_input:
name = user_input
else:
name = "Anonymous"
真实场景:在处理可选参数时,这个特性非常有用:
def greet(name=None):
# 如果 name 是 None 或空,使用默认值
name = name or "World"
return f"Hello, {name}!"
print(greet()) # "Hello, World!"
print(greet("Alice")) # "Hello, Alice!"
C# 得这样写:
string Greet(string name = null)
{
name = name ?? "World";
return $"Hello, {name}!";
}
赋值运算符
C# 版本:
int x = 5;
x += 3; // x = x + 3
x -= 2; // x = x - 2
x *= 4; // x = x * 4
x /= 2; // x = x / 2
x %= 3; // x = x % 3
x &= 0xFF; // 按位与赋值
x |= 0x01; // 按位或赋值
x <<= 1; // 左移赋值
Python 版本:
x = 5
x += 3 # x = x + 3
x -= 2 # x = x - 2
x *= 4 # x = x * 4
x /= 2 # x = x / 2
x %= 3 # x = x % 3
x //= 2 # 整除赋值(Python 独有)
x **= 2 # 幂赋值(Python 独有)
x &= 0xFF # 按位与赋值
x <<= 1 # 左移赋值
Python 多了 //=(整除赋值)和 **=(幂赋值),这两个是 C# 没有的。
三元表达式
C# 版本:
int x = 5;
string result = x > 0 ? "正数" : "非正数";
// C# 9+ 模式匹配
string result2 = x switch
{
> 0 => "正数",
< 0 => "负数",
_ => "零"
};
Python 版本:
x = 5
result = "正数" if x > 0 else "非正数"
# Python 3.10+ match-case(类似 C# 的 switch)
match x:
case x if x > 0:
result2 = "正数"
case x if x < 0:
result2 = "负数"
case _:
result2 = "零"
C# 的三元表达式是 条件 ? 值1 : 值2,Python 的是 值1 if 条件 else 值2——顺序反过来了。
身份运算符
C# 版本:
object a = new object();
object b = a;
object c = new object();
bool same = ReferenceEquals(a, b); // true(同一引用)
bool different = ReferenceEquals(a, c); // false(不同引用)
Python 版本:
a = [1, 2, 3]
b = a
c = [1, 2, 3]
same = a is b # True(同一对象)
different = a is c # False(不同对象)
value_equal = a == c # True(值相等)
# None 比较
x = None
if x is None: # 推荐用 is 比较 None
print("x 是 None")
C# 用 ReferenceEquals() 比较引用,Python 用 is 比较身份。Python 的 is 比 C# 的方法调用简洁多了。
为什么 Python 用 is 而不是 ==?
因为 is 比较的是对象身份(内存地址),== 比较的是值。对于 None 这种单例对象,用 is 更高效,也更符合 Python 的惯例。
设计哲学
C# 的哲学是显式运算符——每个运算符都有明确的含义,类型安全,遵循 C 风格的运算符设计。
Python 的哲学是语法糖——链式比较让代码更简洁,** 幂运算让公式更自然,and/or/not 比 &&/||/! 更易读。
C# 像是给你一套标准的工具箱,每个工具都有明确的用途; Python 像是给你一套多功能工具,有些工具还能组合使用。
迁移指南:C# 开发者最容易犯的错
-
以为
/整数除法会截断:Python 的/始终返回浮点数 -
忘记
**幂运算:C# 没有内置幂运算符 -
以为
and/or返回布尔值:Python 的and/or返回实际值 -
用
==比较 None:Python 推荐用is比较 None -
忘记链式比较:Python 支持
0 < x < 10这种写法
坑点提醒
除法陷阱——Python 的除法始终返回浮点数:
print(10 / 2) # 5.0(不是 5)
print(10 // 3) # 3(整除)
取余符号——Python 的取余结果符号和除数一致:
print(-7 % 3) # 2(不是 -1)
print(7 % -3) # -2(不是 1)
链式比较的陷阱——链式比较是"全链路"求值:
x = 5
# 0 < x < 10 等价于 (0 < x) and (x < 10)
# 但要注意短路求值
print(0 < x < 10 / 0) # 会报错!
海象运算符——Python 3.8+ 的新特性:
# 在表达式中赋值
if (n := len([1, 2, 3])) > 2:
print(f"长度是 {n}") # 3
# 但不要滥用,会影响可读性
一句话总结
Python 的链式比较
0 < x < 10是真正的"语法糖",C# 想这么写得编译器报错。
下一篇咱们来聊聊字符串操作——Python 的切片语法 s[1:4] 比 C# 的 Substring 简洁太多了,还有那个一行代码就能反转字符串的 s[::-1]。
📦 代码仓库:
💬 欢迎点赞、收藏、转发,你的支持是我持续创作的动力!
更多推荐

所有评论(0)