2010-09-12 712 views
2

在IronPython中获取.net IEnumerable<T>的最快方式是什么? Python标准len()函数似乎不起作用。获取IEnumerable的长度?

我知道我可以做

len(list(my_enumerable)) 

list(my_enumerable).Count 

但是,这可能会比需要的慢。

回答

4

你知道吗其实执行IEnumerable<T>?如果是这样,你可以使用Enumerable.Count(IEnumerable<T> source)(LINQ to Objects的一部分)。

我不知道非泛型IEnumerable的等价物 - 尽管您可以轻松地实现这样的方法。在C#中它会是这个样子:

public static int Count(IEnumerable source) 
{ 
    if (source == null) 
    { 
     throw new ArgumentNullException("source"); 
    } 

    // Optimization for ICollection implementations (e.g. arrays, ArrayList) 
    ICollection collection = source as ICollection; 
    if (collection != null) 
    { 
     return collection.Count; 
    } 

    IEnumerator iterator = source.GetEnumerator(); 
    try 
    { 
     int count = 0; 
     while (iterator.MoveNext()) 
     { 
      count++; 
     } 
     return count; 
    } 
    finally 
    { 
     IDisposable disposable = iterator as IDisposable; 
     if (disposable != null) 
     { 
      disposable.Dispose(); 
     } 
    } 
} 

注意,在最后的迭代器的配置是很重要的 - 但你不能用using声明为IEnumerator本身没有实现IDisposable(不像IEnumerator<T>)。

当然,您可以将它用作类库中的C#以从IronPython调用,或者将代码自己转换为IronPython。

+0

你说得对,它实际上是'IEnumerable '。忘记那里是有区别的。谢谢! – mpen 2010-09-12 07:39:51

+0

您还应该查找'ICollection ',因为某些集合实现了一个接口,而不是另一个接口。 – Gabe 2010-09-12 07:42:03

+0

@Gabe:我假设如果它是一个泛型集合,Mark会使用Enumerable.Count代替:)检查'ICollection '在这里会比较棘手,因为我们没有'T'来测试。你需要进行思考,并且有点混乱。 – 2010-09-12 07:46:40