你能在IronPython中使用LINQ类型和扩展方法吗?

时间:2009-03-09 23:53:22

标签: linq ironpython

是否可以在IronPython中使用LINQ类型和扩展方法?

如果是这样怎么样?还有更多的pythonic做同样的事情吗?

4 个答案:

答案 0 :(得分:40)

IronPython 2.7最终通过clr.ImportExtensions方法填补了这一空白,该方法将扩展方法从命名空间添加到目标类型,例如。

>& 'C:\Program Files\IronPython 2.7\ipy.exe'
IronPython 2.7 (2.7.0.40) on .NET 4.0.30319.225
Type "help", "copyright", "credits" or "license" for more information.
>>> import clr
>>> clr.AddReference("System.Core")
>>> from System.Collections.Generic import List
>>> dir (List)
['Add', 'AddRange', 'AsReadOnly', 'BinarySearch', 'Capacity', 'Clear', 'Contains', 'ConvertAll', 'CopyTo', 'Count', 'Enu
merator', 'Equals', 'Exists', 'Find', 'FindAll', 'FindIndex', 'FindLast', 'FindLastIndex', 'ForEach', 'GetEnumerator', '
GetHashCode', 'GetRange', 'GetType', 'IndexOf', 'Insert', 'InsertRange', 'IsReadOnly', 'IsSynchronized', 'Item', 'LastIn
dexOf', 'MemberwiseClone', 'ReferenceEquals', 'Remove', 'RemoveAll', 'RemoveAt', 'RemoveRange', 'Reverse', 'Sort', 'Sync
Root', 'ToArray', 'ToString', 'TrimExcess', 'TrueForAll', '__add__', '__class__', '__contains__', '__delattr__', '__doc_
_', '__format__', '__getattribute__', '__getitem__', '__hash__', '__init__', '__iter__', '__len__', '__new__', '__reduce
__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__']
>>> import System
>>> clr.ImportExtensions(System.Linq)
>>> dir (List)
['Add', 'AddRange', 'Aggregate', 'All', 'Any', 'AsEnumerable', 'AsParallel', 'AsQueryable', 'AsReadOnly', 'Average', 'Bi
narySearch', 'Capacity', 'Cast', 'Clear', 'Concat', 'Contains', 'ConvertAll', 'CopyTo', 'Count', 'DefaultIfEmpty', 'Dist
inct', 'ElementAt', 'ElementAtOrDefault', 'Enumerator', 'Equals', 'Except', 'Exists', 'Find', 'FindAll', 'FindIndex', 'F
indLast', 'FindLastIndex', 'First', 'FirstOrDefault', 'ForEach', 'GetEnumerator', 'GetHashCode', 'GetRange', 'GetType',
'GroupBy', 'GroupJoin', 'IndexOf', 'Insert', 'InsertRange', 'Intersect', 'IsReadOnly', 'IsSynchronized', 'Item', 'Join',
 'Last', 'LastIndexOf', 'LastOrDefault', 'LongCount', 'Max', 'MemberwiseClone', 'Min', 'OfType', 'OrderBy', 'OrderByDesc
ending', 'ReferenceEquals', 'Remove', 'RemoveAll', 'RemoveAt', 'RemoveRange', 'Reverse', 'Select', 'SelectMany', 'Sequen
ceEqual', 'Single', 'SingleOrDefault', 'Skip', 'SkipWhile', 'Sort', 'Sum', 'SyncRoot', 'Take', 'TakeWhile', 'ToArray', '
ToDictionary', 'ToList', 'ToLookup', 'ToString', 'TrimExcess', 'TrueForAll', 'Union', 'Where', 'Zip', '__add__', '__clas
s__', '__contains__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__getitem__', '__hash__', '__init__',
 '__iter__', '__len__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__'
, '__str__', '__subclasshook__']
>>>

使其符合IronRuby 1.1的using_clr_extensions方法。

答案 1 :(得分:23)

您可以使用列表推导完成LINQ的一些操作:

[myFunc(i) for i in numbers if i > 3]

或者你可以使用map,reduce和filter:

map(myFunc, filter(lambda x: x > 3, numbers))

但是列表推导比使用函数式编程结构更加“Pythonic”。为了减少事情,请考虑使用“”。join sum 。您可以使用任意所有

检查整个迭代的真值

请记住这些翻译:

Select -> map
Where -> filter
Aggregate -> reduce

你会很顺利的!

答案 2 :(得分:11)

IronPython 2.7.1中,您为此用例提供了 clr.ImportExtensions

import clr
clr.AddReference("System.Core")
import System
clr.ImportExtensions(System.Linq)

# will print 3 and 4 :)
[2, 3, 4].Where(lambda x: x != 2).ToList().ForEach(System.Console.WriteLine)

一点背景:IronPython 2.7最初引入了此功能,但有an issue阻止它真正可用。

答案 3 :(得分:3)

我{LIN}扩展方法的described a C# wrapper class来实现类似于IronPython中C#的'链式扩展方法'语法的语法。

我的想法是在IEnumerable周围设置一种简单调用扩展方法的装饰器类。可能这个包装类也可以在IronPython中编写,但我还不能熟练使用python: - )

public class ToLinq<T> : IEnumerable<T>
{
    private readonly IEnumerable<T> _wrapped;

    public ToLinq(IEnumerable<T> wrapped)
    {
       _wrapped = wrapped;
    }

    public ToLinq<T> Where(Func<T, bool> predicate)
    {
        return new ToLinq<T>(_wrapped.Where(predicate));
    }


    // ... similar methods for other operators like Select, Count, Any, ...

}

这允许使用与此类似的语法:

johns = ToLinq[Customer](customers)\
          .Where(lambda c: c.Name.StartsWith("John"))\
          .Select(lambda c: c.Name)

免责声明:这是我尝试作为学习练习的东西,我没有在现实世界的项目中使用它。