2010-09-12 95 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