上周面试,面试官冷不丁问了一句:"Python 的 lambda 和 C# 的 Lambda 有什么区别?"我脱口而出:"都是匿名函数嘛,差不多。"面试官笑了笑:"那你给我分别写一个接受任意数量参数的版本?"

那一刻我才意识到——C# 的 Lambda 和 Python 的 lambda 虽然长得像,骨子里完全不是一回事。C# 的 Lambda 是"全能选手",Python 的 lambda 是"临时工"。

基础语法对比

C# 版本:

// Lambda 表达式
Func<int, int> square = x => x * x;
Func<int, int, int> add = (a, b) => a + b;
Action<string> print = msg => Console.WriteLine(msg);

// 带代码块的 Lambda
Func<int, int, int> divide = (a, b) =>
{
    if (b == 0)
        throw new DivideByZeroException();
    return a / b;
};

Python 版本:

# Lambda 表达式(只能是一行)
square = lambda x: x * x
add = lambda a, b: a + b
print_msg = lambda msg: print(msg)

# Python 的 lambda 只能是单个表达式
# 不能写多行代码块
# divide = lambda a, b: if b == 0: ...  # 语法错误!

对比一下:

对比项 C# Python
语法 x => x * 2 lambda x: x * 2
多行代码 支持(用大括号) 不支持(只能单表达式)
类型声明 必须指定参数类型 不需要
返回值 自动推断或显式 return 自动返回表达式结果
语句 可以包含任意语句 只能是表达式

C# 的 Lambda 是"完整版",Python 的是"精简版"。

用法场景对比

作为参数传递

C# 版本:

// 在 LINQ 中使用
var numbers = new List<int> { 1, 2, 3, 4, 5 };

// Lambda 作为参数
var doubled = numbers.Select(x => x * 2).ToList();
var evens = numbers.Where(x => x % 2 == 0).ToList();
var sum = numbers.Aggregate(0, (acc, x) => acc + x);

// 自定义方法接受 Lambda
public List<T> Filter<T>(List<T> list, Func<T, bool> predicate)
{
    return list.Where(predicate).ToList();
}

var result = Filter(numbers, x => x > 3);

Python 版本:

# 在内置函数中使用
numbers = [1, 2, 3, 4, 5]

# Lambda 作为参数
doubled = list(map(lambda x: x * 2, numbers))
evens = list(filter(lambda x: x % 2 == 0, numbers))
sum_result = reduce(lambda acc, x: acc + x, numbers)

# 自定义函数接受 Lambda
def filter_list(lst, predicate):
    return [x for x in lst if predicate(x)]

result = filter_list(numbers, lambda x: x > 3)

C# 的 Lambda 配合 LINQ 使用,Python 的配合 map/filter 使用。

作为返回值

C# 版本:

// 返回 Lambda
public Func<int, int> Multiplier(int factor)
{
    return x => x * factor;
}

var triple = Multiplier(3);
Console.WriteLine(triple(5));  // 15

// 多行 Lambda 作为返回值
public Func<int, int, int> CreateCalculator(string operation)
{
    return (a, b) => operation switch
    {
        "add" => a + b,
        "sub" => a - b,
        "mul" => a * b,
        _ => throw new ArgumentException()
    };
}

Python 版本:

# 返回 Lambda
def multiplier(factor):
    return lambda x: x * factor

triple = multiplier(3)
print(triple(5))  # 15

# Python 的 lambda 只能是单表达式
# 不能写多行逻辑,所以复杂场景要用普通函数
def create_calculator(operation):
    if operation == "add":
        return lambda a, b: a + b
    elif operation == "sub":
        return lambda a, b: a - b
    elif operation == "mul":
        return lambda a, b: a * b
    else:
        raise ValueError(f"Unknown operation: {operation}")

C# 的 Lambda 可以包含复杂逻辑,Python 的只能是简单表达式。

Lambda 对比普通函数

C# 版本:

// Lambda vs 普通方法
Func<int, int, int> addLambda = (a, b) => a + b;

int AddMethod(int a, int b)
{
    return a + b;
}

// Lambda 可以访问外部变量(闭包)
int multiplier = 10;
Func<int, int> multiply = x => x * multiplier;

Python 版本:

# Lambda vs 普通函数
add_lambda = lambda a, b: a + b

def add_function(a, b):
    return a + b

# Lambda 也可以访问外部变量(闭包)
multiplier = 10
multiply = lambda x: x * multiplier

Python 的 lambda 就是普通函数的语法糖,C# 的 Lambda 有独立的语法地位。

常见用法模式

排序

C# 版本:

// 按属性排序
var users = new List<User> { /* ... */ };
users.Sort((a, b) => a.Name.CompareTo(b.Name));
users = users.OrderBy(u => u.Age).ToList();
users = users.OrderByDescending(u => u.Salary).ToList();

Python 版本:

# 按属性排序
users = [{"name": "张三", "age": 25}, /* ... */]
users.sort(key=lambda u: u["name"])
users.sort(key=lambda u: u["age"])
users.sort(key=lambda u: u["salary"], reverse=True)

字典转换

C# 版本:

// 用 Lambda 做转换
var dict = new Dictionary<string, int> { ["a"] = 1, ["b"] = 2 };
var values = dict.Select(kv => kv.Value).ToList();
var newDict = dict.ToDictionary(kv => kv.Key, kv => kv.Value * 2);

Python 版本:

# 用 Lambda 做转换
dict_data = {"a": 1, "b": 2}
values = list(map(lambda x: x[1], dict_data.items()))
new_dict = {k: v * 2 for k, v in dict_data.items()}

设计哲学

C# 的 Lambda 是"完整的匿名函数"——支持多行代码、闭包、泛型推断,是 LINQ 的核心。

Python 的 lambda 是"轻量级语法糖"——只能写单个表达式,复杂逻辑还是用普通函数。

C# 的 Lambda 像是"迷你函数",能干的事和普通函数差不多; Python 的 lambda 像是"一次性纸杯",用完就扔,别指望它能干重活。

坑点提醒

Python 的 lambda 只能是表达式——不能包含语句:

# 错误!lambda 不能包含语句
# func = lambda x: print(x) if x > 0 else None  # 语法错误

# 正确写法:用三元表达式
func = lambda x: print(x) if x > 0 else None  # 这是表达式,可以

# 或者直接用普通函数
def func(x):
    if x > 0:
        print(x)

C# 的 Lambda 会捕获变量引用——循环中的常见坑:

// 错误!所有 Lambda 捕获的是同一个变量
var actions = new List<Action>();
for (int i = 0; i < 5; i++)
{
    actions.Add(() => Console.WriteLine(i));
}
// 执行所有 action,输出都是 5!

// 正确写法:创建局部变量
var actions = new List<Action>();
for (int i = 0; i < 5; i++)
{
    int temp = i;
    actions.Add(() => Console.WriteLine(temp));
}
// 输出 0, 1, 2, 3, 4

Python 的 lambda 同样捕获引用——同样的坑:

# 错误!
funcs = []
for i in range(5):
    funcs.append(lambda: print(i))

for f in funcs:
    f()  # 都输出 4!

# 正确写法:用默认参数创建新作用域
funcs = []
for i in range(5):
    funcs.append(lambda i=i: print(i))

for f in funcs:
    f()  # 输出 0, 1, 2, 3, 4

不要滥用 Lambda——保持可读性:

# 不好:过度使用 lambda
data = list(map(lambda x: x * 2, filter(lambda x: x > 0, numbers)))

# 好:用列表推导式
data = [x * 2 for x in numbers if x > 0]

迁移指南:C# 开发者最容易犯的错

这一章节的内容比较特殊,迁移指南会在后续文章中详细讨论。

一句话总结

C# 的 Lambda 是"全能匿名函数",Python 的 lambda 是"一次性纸杯"——好用但别指望它能干重活。

下一篇咱们来聊聊列表推导式 vs LINQ——两种语言处理集合的"语法糖"大比拼。


📦 示例代码:C# 转 Python 全系列配套练习代码(含 48 章示例)

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

上周面试,面试官冷不丁问了一句:"Python 的 lambda 和 C# 的 Lambda 有什么区别?"我脱口而出:"都是匿名函数嘛,差不多。"面试官笑了笑:"那你给我分别写一个接受任意数量参数的版本?"

那一刻我才意识到——C# 的 Lambda 和 Python 的 lambda 虽然长得像,骨子里完全不是一回事。C# 的 Lambda 是"全能选手",Python 的 lambda 是"临时工"。

基础语法对比

C# 版本:

// Lambda 表达式
Func<int, int> square = x => x * x;
Func<int, int, int> add = (a, b) => a + b;
Action<string> print = msg => Console.WriteLine(msg);

// 带代码块的 Lambda
Func<int, int, int> divide = (a, b) =>
{
    if (b == 0)
        throw new DivideByZeroException();
    return a / b;
};

Python 版本:

# Lambda 表达式(只能是一行)
square = lambda x: x * x
add = lambda a, b: a + b
print_msg = lambda msg: print(msg)

# Python 的 lambda 只能是单个表达式
# 不能写多行代码块
# divide = lambda a, b: if b == 0: ...  # 语法错误!

对比一下:

对比项 C# Python
语法 x => x * 2 lambda x: x * 2
多行代码 支持(用大括号) 不支持(只能单表达式)
类型声明 必须指定参数类型 不需要
返回值 自动推断或显式 return 自动返回表达式结果
语句 可以包含任意语句 只能是表达式

C# 的 Lambda 是"完整版",Python 的是"精简版"。

用法场景对比

作为参数传递

C# 版本:

// 在 LINQ 中使用
var numbers = new List<int> { 1, 2, 3, 4, 5 };

// Lambda 作为参数
var doubled = numbers.Select(x => x * 2).ToList();
var evens = numbers.Where(x => x % 2 == 0).ToList();
var sum = numbers.Aggregate(0, (acc, x) => acc + x);

// 自定义方法接受 Lambda
public List<T> Filter<T>(List<T> list, Func<T, bool> predicate)
{
    return list.Where(predicate).ToList();
}

var result = Filter(numbers, x => x > 3);

Python 版本:

# 在内置函数中使用
numbers = [1, 2, 3, 4, 5]

# Lambda 作为参数
doubled = list(map(lambda x: x * 2, numbers))
evens = list(filter(lambda x: x % 2 == 0, numbers))
sum_result = reduce(lambda acc, x: acc + x, numbers)

# 自定义函数接受 Lambda
def filter_list(lst, predicate):
    return [x for x in lst if predicate(x)]

result = filter_list(numbers, lambda x: x > 3)

C# 的 Lambda 配合 LINQ 使用,Python 的配合 map/filter 使用。

作为返回值

C# 版本:

// 返回 Lambda
public Func<int, int> Multiplier(int factor)
{
    return x => x * factor;
}

var triple = Multiplier(3);
Console.WriteLine(triple(5));  // 15

// 多行 Lambda 作为返回值
public Func<int, int, int> CreateCalculator(string operation)
{
    return (a, b) => operation switch
    {
        "add" => a + b,
        "sub" => a - b,
        "mul" => a * b,
        _ => throw new ArgumentException()
    };
}

Python 版本:

# 返回 Lambda
def multiplier(factor):
    return lambda x: x * factor

triple = multiplier(3)
print(triple(5))  # 15

# Python 的 lambda 只能是单表达式
# 不能写多行逻辑,所以复杂场景要用普通函数
def create_calculator(operation):
    if operation == "add":
        return lambda a, b: a + b
    elif operation == "sub":
        return lambda a, b: a - b
    elif operation == "mul":
        return lambda a, b: a * b
    else:
        raise ValueError(f"Unknown operation: {operation}")

C# 的 Lambda 可以包含复杂逻辑,Python 的只能是简单表达式。

Lambda 对比普通函数

C# 版本:

// Lambda vs 普通方法
Func<int, int, int> addLambda = (a, b) => a + b;

int AddMethod(int a, int b)
{
    return a + b;
}

// Lambda 可以访问外部变量(闭包)
int multiplier = 10;
Func<int, int> multiply = x => x * multiplier;

Python 版本:

# Lambda vs 普通函数
add_lambda = lambda a, b: a + b

def add_function(a, b):
    return a + b

# Lambda 也可以访问外部变量(闭包)
multiplier = 10
multiply = lambda x: x * multiplier

Python 的 lambda 就是普通函数的语法糖,C# 的 Lambda 有独立的语法地位。

常见用法模式

排序

C# 版本:

// 按属性排序
var users = new List<User> { /* ... */ };
users.Sort((a, b) => a.Name.CompareTo(b.Name));
users = users.OrderBy(u => u.Age).ToList();
users = users.OrderByDescending(u => u.Salary).ToList();

Python 版本:

# 按属性排序
users = [{"name": "张三", "age": 25}, /* ... */]
users.sort(key=lambda u: u["name"])
users.sort(key=lambda u: u["age"])
users.sort(key=lambda u: u["salary"], reverse=True)

字典转换

C# 版本:

// 用 Lambda 做转换
var dict = new Dictionary<string, int> { ["a"] = 1, ["b"] = 2 };
var values = dict.Select(kv => kv.Value).ToList();
var newDict = dict.ToDictionary(kv => kv.Key, kv => kv.Value * 2);

Python 版本:

# 用 Lambda 做转换
dict_data = {"a": 1, "b": 2}
values = list(map(lambda x: x[1], dict_data.items()))
new_dict = {k: v * 2 for k, v in dict_data.items()}

设计哲学

C# 的 Lambda 是"完整的匿名函数"——支持多行代码、闭包、泛型推断,是 LINQ 的核心。

Python 的 lambda 是"轻量级语法糖"——只能写单个表达式,复杂逻辑还是用普通函数。

C# 的 Lambda 像是"迷你函数",能干的事和普通函数差不多; Python 的 lambda 像是"一次性纸杯",用完就扔,别指望它能干重活。

坑点提醒

Python 的 lambda 只能是表达式——不能包含语句:

# 错误!lambda 不能包含语句
# func = lambda x: print(x) if x > 0 else None  # 语法错误

# 正确写法:用三元表达式
func = lambda x: print(x) if x > 0 else None  # 这是表达式,可以

# 或者直接用普通函数
def func(x):
    if x > 0:
        print(x)

C# 的 Lambda 会捕获变量引用——循环中的常见坑:

// 错误!所有 Lambda 捕获的是同一个变量
var actions = new List<Action>();
for (int i = 0; i < 5; i++)
{
    actions.Add(() => Console.WriteLine(i));
}
// 执行所有 action,输出都是 5!

// 正确写法:创建局部变量
var actions = new List<Action>();
for (int i = 0; i < 5; i++)
{
    int temp = i;
    actions.Add(() => Console.WriteLine(temp));
}
// 输出 0, 1, 2, 3, 4

Python 的 lambda 同样捕获引用——同样的坑:

# 错误!
funcs = []
for i in range(5):
    funcs.append(lambda: print(i))

for f in funcs:
    f()  # 都输出 4!

# 正确写法:用默认参数创建新作用域
funcs = []
for i in range(5):
    funcs.append(lambda i=i: print(i))

for f in funcs:
    f()  # 输出 0, 1, 2, 3, 4

不要滥用 Lambda——保持可读性:

# 不好:过度使用 lambda
data = list(map(lambda x: x * 2, filter(lambda x: x > 0, numbers)))

# 好:用列表推导式
data = [x * 2 for x in numbers if x > 0]

迁移指南:C# 开发者最容易犯的错

这一章节的内容比较特殊,迁移指南会在后续文章中详细讨论。

一句话总结

C# 的 Lambda 是"全能匿名函数",Python 的 lambda 是"一次性纸杯"——好用但别指望它能干重活。

下一篇咱们来聊聊列表推导式 vs LINQ——两种语言处理集合的"语法糖"大比拼。


📦 示例代码:C# 转 Python 全系列配套练习代码(含 48 章示例)

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

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐