C#转Python第2.3篇上周帮同事 review 代码他一行 Python 让我愣了 5 秒上周帮同事 review 代码他甩过来一行 Python[x * 2 for x in nums if x 0]。我愣了 5 秒——这不就是我用 LINQ 写了三年的Where().Select()吗一行顶三行Python 玩家果然任性。不过等我看到后面的需求——分组、聚合、延迟执行——我又默默打开了 C# 的 LINQ。两种写法各有各的杀手锏C# 的 LINQ 像是流水线Python 的推导式像是压缩包。基础语法对比C# 版本var numbers new Listint { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; // 筛选 var evens numbers.Where(x x % 2 0).ToList(); // 转换 var doubled numbers.Select(x x * 2).ToList(); // 排序 var sorted numbers.OrderByDescending(x x).ToList(); // 聚合 var sum numbers.Sum(); var avg numbers.Average(); // 链式调用 var result numbers .Where(x x 3) .Select(x x * 2) .OrderBy(x x) .ToList(); // C# 12 集合表达式更简洁 int[] nums [1, 2, 3, 4, 5]; Listint list [1, 2, 3, 4, 5]; IEnumerableint more [.. nums, 6, 7, 8]; // 展开运算符Python 版本numbers [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # 筛选 evens [x for x in numbers if x % 2 0] # 转换 doubled [x * 2 for x in numbers] # 排序 sorted_list sorted(numbers, reverseTrue) # 聚合 total sum(numbers) avg sum(numbers) / len(numbers) # 链式操作 result [x * 2 for x in numbers if x 3] result sorted([x * 2 for x in numbers if x 3])对比一下操作C# LINQPython 列表推导式筛选list.Where(x x 0)[x for x in list if x 0]转换list.Select(x x * 2)[x * 2 for x in list]排序list.OrderBy(x x)sorted(list)聚合list.Sum()sum(list)链式.Where().Select().ToList()[... for x in list if ...]C# 的 LINQ 是方法链Python 的推导式是表达式压缩。复杂操作对比多条件筛选C# 版本var users GetUsers(); // 多条件筛选 var result users .Where(u u.Age 18) .Where(u u.IsActive) .Where(u u.Score 80) .ToList(); // 或者用 连接 var result2 users .Where(u u.Age 18 u.IsActive u.Score 80) .ToList();Python 版本users get_users() # 多条件筛选 result [u for u in users if u[age] 18 and u[is_active] and u[score] 80] # 或者分行写 result [ u for u in users if u[age] 18 and u[is_active] and u[score] 80 ]嵌套循环C# 版本// 笛卡尔积 var colors new[] { 红, 蓝, 绿 }; var sizes new[] { S, M, L }; var combinations colors .SelectMany(c sizes, (c, s) new { Color c, Size s }) .ToList(); // 或者用嵌套 Select var combinations2 colors .SelectMany(c sizes.Select(s new { Color c, Size s })) .ToList();Python 版本# 笛卡尔积 colors [红, 蓝, 绿] sizes [S, M, L] combinations [(c, s) for c in colors for s in sizes] # 等价于 combinations [] for c in colors: for s in sizes: combinations.append((c, s))Python 的嵌套循环更直观C# 需要SelectMany。字典推导C# 版本var users new ListUser { /* ... */ }; // 转换为字典 var userDict users.ToDictionary(u u.Id, u u.Name); // 用 LINQ 生成字典 var priceDict products .Where(p p.IsActive) .ToDictionary(p p.Id, p p.Price);Python 版本users [{id: 1, name: 张三}, ...] # 字典推导 user_dict {u[id]: u[name] for u in users} # 带条件的字典推导 price_dict { p[id]: p[price] for p in products if p[is_active] }集合推导C# 版本var numbers new Listint { 1, 2, 2, 3, 3, 3, 4 }; // 用 HashSet 去重 var unique new HashSetint(numbers); // 用 LINQ Distinct var distinct numbers.Distinct().ToList();Python 版本numbers [1, 2, 2, 3, 3, 3, 4] # 集合推导自动去重 unique {x for x in numbers} # {1, 2, 3, 4} # 列表去重保持顺序 distinct list(dict.fromkeys(numbers)) # [1, 2, 3, 4]性能对比C# 版本// LINQ 延迟执行 var query numbers.Where(x x 0); // 不会立即执行 var result query.ToList(); // 这里才执行 // 可以利用延迟执行优化 var result numbers .Where(x x 0) // 延迟 .Select(x x * 2) // 延迟 .Take(10) // 延迟 .ToList(); // 执行只处理前 10 个Python 版本# 列表推导式立即执行 result [x * 2 for x in numbers if x 0] # 立即创建整个列表 # 生成器表达式延迟执行 result (x * 2 for x in numbers if x 0) # 不会立即创建列表 # 用 next() 取第一个 first next(x * 2 for x in numbers if x 0) # 或者用生成器配合函数 result list(islice( (x * 2 for x in numbers if x 0), 10 ))C# 的 LINQ 天然支持延迟执行Python 需要用生成器表达式。可读性对比C# 版本// 复杂的链式调用 var result orders .Where(o o.Status OrderStatus.Completed) .Where(o o.OrderDate DateTime.Now.AddDays(-30)) .SelectMany(o o.Items) .GroupBy(i i.ProductId) .Select(g new { ProductId g.Key, TotalQuantity g.Sum(i i.Quantity), TotalAmount g.Sum(i i.Quantity * i.Price) }) .OrderByDescending(x x.TotalAmount) .Take(10) .ToList();Python 版本# 等价的 Python 写法 result [ { product_id: product_id, total_quantity: sum(i[quantity] for i in items), total_amount: sum(i[quantity] * i[price] for i in items) } for product_id, items in groupby( [ i for o in orders if o[status] completed and o[order_date] datetime.now() - timedelta(days30) for i in o[items] ], keylambda i: i[product_id] ) ] # 或者用 Pandas更清晰 import pandas as pd df pd.DataFrame(orders) result ( df[df[status] completed] .query(order_date thirty_days_ago) .explode(items) .groupby(product_id) .agg({quantity: sum, amount: sum}) .nlargest(10, amount) )C# 的 LINQ 链更清晰Python 的复杂推导式可读性较差。设计哲学C# 的 LINQ 是方法链模式——每个操作返回新的序列可以链式调用适合复杂的数据处理管道。Python 的推导式是表达式压缩——用一行代码表达复杂的逻辑适合简单的转换和筛选。C# 的 LINQ 像是流水线每个环节清晰可见 Python 的推导式像是压缩包解压后才能看清内部。坑点提醒Python 推导式的变量泄漏——变量会泄漏到外部作用域x 10 result [x for x in range(5)] print(x) # 4不是 10 了 # 避免方法Python 3.0 的推导式有自己的作用域 # 但在旧版本中推导式变量会泄漏过度嵌套的推导式——可读性灾难# 不好嵌套太深 result [ f(x, y) for x in range(10) for y in range(10) if g(x, y) for f in [h1, h2, h3] if condition(f, x, y) ] # 好拆分成多步 filtered [(x, y) for x in range(10) for y in range(10) if g(x, y)] result [f(x, y) for x, y in filtered for f in [h1, h2, h3] if condition(f, x, y)]C# 的 LINQ 方法命名——英语不好会很痛苦// 需要记住很多方法名 // Where, Select, SelectMany, OrderBy, ThenBy // GroupBy, Distinct, Except, Intersect, Union // Any, All, First, Last, Single // Sum, Average, Min, Max, Count // Python 的关键字更直观 # for, in, if, sorted, sum, len性能陷阱——不必要的转换// 不好多次转换 var result list.Where(x x 0).Select(x x * 2).ToList(); // 好一次转换 var result list.Where(x x 0).Select(x x * 2).ToList(); // 上面两个一样但注意不要在循环中多次调用 ToList()# 不好多次创建列表 result1 [x for x in numbers if x 0] result2 [x * 2 for x in result1] # 好一次完成 result [x * 2 for x in numbers if x 0]迁移指南C# 开发者最容易犯的错混淆推导式和生成器表达式[x for x in list]立即创建列表(x for x in list)是生成器忘记推导式变量泄漏Python 3.12 之前推导式变量会泄漏到外部作用域过度使用推导式复杂逻辑应该用普通循环可读性更重要**用sorted()代替.OrderBy()**sorted()返回新列表原列表不变**用sum()/len()代替.Average()**Python 没有内置的average()函数**用in代替.Contains()**x in list比list.__contains__(x)更 Pythonic一句话总结C# 的 LINQ 是流水线Python 的推导式是压缩包——都能处理集合但风格完全不同。下一篇咱们来聊聊生成器与迭代器——C# 的yield return和 Python 的yield几乎一样的设计哲学示例代码C# 转 Python 全系列配套练习代码含 48 章示例GitHubGitHub - LadyKiller1025/csharp-python-demos: C# vs Python 学习系列 - Demo 代码合集 · GitHubGiteehttps://gitee.com/qakjhzx/csharp-python-demos 欢迎点赞、收藏、转发你的支持是我持续创作的动力