C#转Python第2.2篇:面试官问我 Python 的 lambda 和 C# 的 Lambda 有什么区别
上周面试,面试官冷不丁问了一句:"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 章示例)
💬 欢迎点赞、收藏、转发,你的支持是我持续创作的动力!
更多推荐




所有评论(0)