当前位置:  开发笔记 > 编程语言 > 正文

C#有没有与Python的列表推导相媲美的东西?

如何解决《C#有没有与Python的列表推导相媲美的东西?》经验,为你挑选了3个好方法。

我想在C#中生成一个列表.我错过了python的列表推导.是否有一种C#方式来动态创建集合,如列表推导或生成器表达式在python中做?



1> Matt Campbel..:

如果您使用的是C#3.0(VS2008),则LINQ to Objects可以执行非常类似的操作:

List fooList = new List();
IEnumerable extract = from foo in fooList where foo.Bar > 10 select Foo.Name.ToUpper();



2> Jon Skeet..:

Matt提到了查询表达式.顺便说一下,这些可用于LINQ - 不仅仅是LINQ to Objects.(例如,应用于LINQ to SQL datacontext的相同查询将执行数据库上的过滤器和投影.)

C#3中的查询表达式只是编写普通C#代码的语法糖 - 尽管查询表达式通常最终会调用扩展方法.(他们没有,并且编译器并不关心,但他们通常会这样做.)对于C#查询表达式中不可用但是方法调用支持的集合,可以执行各种操作,因此值得了解这两种语法.例如,Matt的查询表达式为:

List fooList = new List();
IEnumerable extract = from foo in fooList where foo.Bar > 10 select foo.Name.ToUpper();

被"预处理"成:

List fooList = new List();
IEnumerable extract = fooList.Where(foo => foo.Bar > 10)
                                     .Select(foo => foo.Name.ToUpper());

如果您希望(比方说)基于原始集合中的值的索引进行过滤,则可以使用通过查询表达式不可用的Where的适当重载:

List fooList = new List();
IEnumerable extract = fooList.Where((foo, index) => foo.Bar > 10 + index)
                                     .Select(foo => foo.Name.ToUpper());

或者您可以找到符合条件的最长名称的长度:

List fooList = new List();
int longestName = fooList.Where((foo, index) => foo.Bar > 10 + index)
                         .Select(foo => foo.Name)
                         .Max();

(你不必须做的不同的方法投影和最大-有一个Max过载,这需要投影为好.)

我的观点是,使用扩展方法可以非常轻松地构建复杂的查询.

你也提到了Python生成器--C#以迭代器块的形式提供它.实际上,这些在实现类似LINQ的运算符时非常有用.(因为LINQ to Objects的大多数都是基于扩展方法的,所以你可以添加自己看起来像LINQ"本机"的运算符 - 虽然你不能自己改变查询表达式语法.)



3> Ray Vega..:

List.ConvertAll通过对现有列表上的每个项执行相同的操作然后返回新集合,行为就像列表推导一样.如果您仍在使用.NET 2.0,这是使用Linq的替代方法.

在Python中,一个简单的列表理解示例:

>>> foo = [1, 2, 3]
>>> bar = [x * 2 for x in foo]
>>> bar
[2, 4, 6]

对于C#3.0,您可以传递一个lambda函数,指定所需的映射函数类型.

public static void Main()
{
    var foo = new List{ 1, 2, 3};
    var bar = foo.ConvertAll(x => x * 2);    // list comprehension

    foreach (var x in bar)
    {
        Console.WriteLine(x);  // should print 2 4 6
    }
}

对于C#2.0,您可以使用Converter委托的匿名方法来执行等效操作.

public static void Main()
{
    List foo = new List(new int[]{ 1, 2, 3});
    List bar = foo.ConvertAll(new Converter(delegate(int x){ return x * 2; }));  // list comprehension

    foreach (int x in bar)
    {
        Console.WriteLine(x);  // should print 2 4 6
    }
}

(注意:使用Arrays可以完成相同的操作 Array.ConvertAll

推荐阅读
爱唱歌的郭少文_
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有