前段时间在知识星球上立了一个Flag,至少写10篇关于 Python,Matlab 和 C# 对比的总结。
这是第 2 篇,从定义和应用两个角度来对比 Python 的匿名函数 与 C# 的Lambda表达式。
Python 匿名函数
在 Python 里有两类函数:
第一类:用 def
关键词定义的正规函数
第二类:用 lambda
关键词定义的匿名函数
python 使用 lambda
关键词来创建匿名函数,而非def
关键词,它没有函数名,其语法结构如下:
lambda argument_list: expression
lambda
- 定义匿名函数的关键词。
argument_list
- 函数参数,它们可以是位置参数、默认参数、关键字参数,和正规函数里的参数类型一样。
:
- 冒号,在函数参数和表达式中间要加个冒号。
expression
- 只是一个表达式,输入函数参数,输出一些值。
注意:
expression
中没有 return 语句,因为 lambda 不需要它来返回,表达式本身结果就是返回值。
匿名函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
【例】
def sqr(x):
return x ** 2
print(sqr)
# <function sqr at 0x000000BABD3A4400>
y = [sqr(x) for x in range(10)]
print(y)
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
lbd_sqr = lambda x: x ** 2
print(lbd_sqr)
# <function <lambda> at 0x000000BABB6AC1E0>
y = [lbd_sqr(x) for x in range(10)]
print(y)
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
sumary = lambda arg1, arg2: arg1 + arg2
print(sumary(10, 20)) # 30
func = lambda *args: sum(args)
print(func(1, 2, 3, 4, 5)) # 15
C# Lambda表达式
Lambda 表达式是 匿名委托 更为简洁的一种写法,这个概念来自函数式编程,很多语言都加入了这个功能。通俗点讲,你需要写一个函数,但是懒得给它起名字,而且懒得写那么多封装和类,并且可能就这个地方调用,其它地方几乎不调用这段代码,那么我们就可以用这个来搞定。
Lambda 运算符:
“=>” 运算符将表达式分为两部分,左边指定输入参数,右边是 Lambda 的主体,表达式或语句块。
Lambda 表达式:
一个参数:param => expr;
多个参数:(param-list) => expr;
【例】
static void Print<T>(List<T> lst)
{
foreach (T item in lst)
{
Console.Write(item + " ");
}
Console.WriteLine(Environment.NewLine);
}
static void Main(string[] args)
{
Func<int, int> sqr = delegate (int x) { return x * x; };
Func<int, int> lbd_sqr = x => x * x;
List<int> y1 = new List<int>();
List<int> y2 = new List<int>();
for (int i = 0; i < 10; i++)
{
y1.Add(sqr(i));
y2.Add(lbd_sqr(i));
}
Print(y1);// 0 1 4 9 16 25 36 49 64 81
Print(y2);// 0 1 4 9 16 25 36 49 64 81
Func<int, int, int> sumary = (arg1, arg2) => arg1 + arg2;
Console.WriteLine(sumary(10, 20)); //30
Func<int[], int> sum = x => x.Sum();
Console.WriteLine(sum(new int[] { 1, 2, 3, 4, 5 }));//15
}
Python 匿名函数
匿名函数 常常应用于函数式编程的高阶函数 (high-order function)中。
如,在 filter
和map
函数中的应用:
filter(function, iterable)
过滤序列,过滤掉不符合条件的元素,返回一个迭代器对象,如果要转换为列表,可以使用 list()
来转换。
【例】
odd = lambda x: x % 2 == 1
templist = filter(odd, [1, 2, 3, 4, 5, 6, 7, 8, 9])
print(list(templist)) # [1, 3, 5, 7, 9]
map(function, *iterables)
根据提供的函数对指定序列做映射。
【例】
m1 = map(lambda x: x ** 2, [1, 2, 3, 4, 5])
print(list(m1))
# [1, 4, 9, 16, 25]
m2 = map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])
print(list(m2))
# [3, 7, 11, 15, 19]
除了 Python 这些内置函数,我们也可以自己定义高阶函数。
【例】
def apply_to_list(fun, some_list):
return fun(some_list)
lst = [1, 2, 3, 4, 5]
print(apply_to_list(sum, lst))
# 15
print(apply_to_list(len, lst))
# 5
print(apply_to_list(lambda x: sum(x) / len(x), lst))
# 3.0
C# Lambda表达式
Lambda 表达式常常应用于 LINQ 的扩展函数中。
Where 扩展:属于System.Linq,基于谓词筛选值序列,返回一个包含输入序列中满足条件的元素集合。
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);
【例】
static void Print<T>(T[] nums)
{
foreach (T item in nums)
{
Console.Write(item + " ");
}
Console.WriteLine(Environment.NewLine);
}
static void Main(string[] args)
{
int[] nums = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int[] result = nums.Where(x => x % 2 == 1).ToArray();
Print(result);// 1 3 5 7 9
}
Select 扩展:属于System.Linq,将序列中的每个元素投影到新表单。
public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector);
【例】
static void Print<T>(T[] nums)
{
foreach (T item in nums)
{
Console.Write(item + " ");
}
Console.WriteLine(Environment.NewLine);
}
static void Main(string[] args)
{
int[] nums = new int[] { 1, 2, 3, 4, 5 };
int[] result = nums.Select(x => x * x).ToArray();
Print(result);//1 4 9 16 25
int[][] nums1 = new int[5][] {
new int[]{ 1,2 },
new int[]{ 3,4 },
new int[]{ 5,6 },
new int[]{ 7,8 },
new int[]{ 9,10 }
};
result = nums1.Select(x => x[0] + x[1]).ToArray();
Print(result);// 3 7 11 15 19
}
【例】
static int Apply_To_List(Func<int[],int> func,int[] list)
{
return func(list);
}
static double Apply_To_List(Func<int[], double> func, int[] list)
{
return func(list);
}
static void Main(string[] args)
{
int[] nums = new int[] { 1, 2, 3, 4, 5 };
int result = Apply_To_List(x => x.Sum(), nums);
Console.WriteLine(result); // 15
result = Apply_To_List(x => x.Length, nums);
Console.WriteLine(result); // 5
double result1 = Apply_To_List(x => 1.0 * x.Sum() / x.Length, nums);
Console.WriteLine(result1); // 3
}
函数式编程是当今比较流行的以简洁著称的一种编程方式。而 匿名函数/Lambda表达式 是这种编程方式的基础。
前段时间看到教务处通知老师们上报线上考试的方案,感觉这个学期可能不会开学了。今天看到通知6月8日毕业生可以申请返校,也就意味着让他们回去收拾东西办理离校手续准备毕业了。不管怎样,希望疫情尽快过去吧。
今天就到这里吧。See You!
当前活动
我是 终身学习者“老马”,一个长期践行“结伴式学习”理念的 中年大叔。
我崇尚分享,渴望成长,于2010年创立了“LSGO软件技术团队”,并加入了国内著名的开源组织“Datawhale”,也是“Dre@mtech”、“智能机器人研究中心”和“大数据与哲学社会科学实验室”的一员。
愿我们一起学习,一起进步,相互陪伴,共同成长。
联系客服