在 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# 开发者最容易犯的错

  1. 以为 / 整数除法会截断:Python 的 / 始终返回浮点数

  2. 忘记 ** 幂运算:C# 没有内置幂运算符

  3. 以为 and/or 返回布尔值:Python 的 and/or 返回实际值

  4. == 比较 None:Python 推荐用 is 比较 None

  5. 忘记链式比较: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]


📦 代码仓库

💬 欢迎点赞、收藏、转发,你的支持是我持续创作的动力!

更多推荐