tags:

views:

48

answers:

1

What's the fastest way to get the length of an .net IEnumerable<T> in IronPython? The Python standard len() function doesn't seem to work on it.

I know I can do

len(list(my_enumerable))

or

list(my_enumerable).Count

But that might be slower than necessary.

+1  A: 

Do you know if it actually implements IEnumerable<T>? If so, you could use Enumerable.Count(IEnumerable<T> source) (part of LINQ to Objects).

I don't know of an equivalent for the non-generic IEnumerable - although you could implement such a method yourself easily enough. In C# it would look something like this:

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();
        }
    }
}

Note that disposing of the iterator at the end is important - but you can't use a using statement as IEnumerator itself doesn't implement IDisposable (unlike IEnumerator<T>).

Of course you could either use that as C# in a class library to call from IronPython, or translate the code into IronPython yourself.

Jon Skeet
You're right, it's actually `IEnumerable<T>`. Forgot there was a difference. Thanks!
Mark
You should also look for `ICollection<T>` because some collections implement one interface but not the other.
Gabe
@Gabe: I was assuming that if it was a generic collection Mark would use Enumerable.Count instead :) Checking for `ICollection<T>` would be relatively tricky here, because we don't have a `T` to test for. You'd need to go into reflection, and it gets somewhat messy.
Jon Skeet