How to get an item from a simple set?

Steven Bethard steven.bethard at gmail.com
Wed Nov 24 12:40:34 EST 2004


Pete Forman wrote:
> Steven Bethard <steven.bethard at gmail.com> writes:
> 
> 
>>I still tend to write the extra line in cases like this -- it
>>guarantees that the set is really the size that I think it is, where
>>the iter(s).next() solution will not raise an exception if the set
>>is actually larger.
> 
> 
> The preceding line in my code is
>   if len(s) == 1:
> 

So is this just one branch of a case statement?  What do you do in the 
case that len(s) != 1?  And which one happens more often?

If I have two possible unpackings of an iterable and I know one is much 
more common than the other, I often do something like:

try:
     x, y = s         # more common unpacking
except ValueError:
     [x], y = s, None # less common ('exceptional') unpacking

This is a reasonable pattern if your code really does favor one branch 
substantially over the other.  But dont' take my word for it. ;)  Here's 
what timeit says:

----- test.py ----
def test_cond(*args):
     if len(args) == 1:
         [x], y = args, None
     elif len(args) == 2:
         x, y = args
     else:
         raise ValueError('wrong number of arguments')

def test_try(*args):
     try:
         x, y = args
     except ValueError:
         [x], y = args, None

def test(fn, single_times, double_times):
     for _ in range(single_times):
         fn(1)
     for _ in range(double_times):
         fn(0, 1)


---- command prompt ----
 >python -m timeit -s "import test" "test.test(test.test_cond, 10, 10)"
10000 loops, best of 3: 26.7 usec per loop

 >python -m timeit -s "import test" "test.test(test.test_try, 10, 10)"
10000 loops, best of 3: 116 usec per loop

 >python -m timeit -s "import test" "test.test(test.test_cond, 1, 100)"
10000 loops, best of 3: 132 usec per loop

 >python -m timeit -s "import test" "test.test(test.test_try, 1, 100)"
10000 loops, best of 3: 99.8 usec per loop


As you can see, when the try/except block is slower when the two 
branches get traversed approximately equally, but faster when one branch 
is substantially favored over the other.

Steve



More information about the Python-list mailing list