[Python-Dev] Retrieve an arbitrary element from asetwithoutremoving it (original) (raw)

Steven D'Aprano steve at pearwood.info
Mon Nov 9 21:16:56 CET 2009


On Tue, 10 Nov 2009 03:40:11 am Björn Lindqvist wrote:

2009/11/6 Raymond Hettinger <python at rcn.com>: > [me] > >> Why not write a short, fast getfirst() function for your utils >> directory and be done with it? >> That could work with sets, mappings, generators, and other >> containers and iterators. >> No need to fatten the set/frozenset API for something so trivial >> and so rarely needed. > > Forgot to post the code.  It is short, fast, and easy.  It is > explicit about handing the case with an empty input.  And it is > specific about which value it returns (always the first iterated > value; not an arbitrary one).  There's no guessing about what it > does.  It gets the job done. > > def first(iterable): >   'Return the first value from a container or iterable.  If empty, > raises LookupError' >   for value in iterable: >       return value >   raise LookupError('no first value; iterable is empty') > > If desired, it is not hard to change to the last time to return a > default value or some other exception.

That function is very nice and genericly lisp-like. Couldn't that one be in the builtins? It would both solve the problem and avoid fattening the set API.

I'm not sure, but isn't that thread-unsafe?

Because sets aren't directly iterable, for value in iterable builds a set_iterator operator. If another thread modifies the set after the set_iterator is built, but before the value is looked up, you will get a mysterious RuntimeError almost impossible to debug.

def first(): # simplified ... for value in iterator: ... return value ... dis.dis(first) 2 0 SETUP_LOOP 15 (to 18) 3 LOAD_GLOBAL 0 (iterator) 6 GET_ITER 7 FOR_ITER 7 (to 17) 10 STORE_FAST 0 (value)

3 13 LOAD_FAST 0 (value) 16 RETURN_VALUE >> 17 POP_BLOCK >> 18 LOAD_CONST 0 (None) 21 RETURN_VALUE

Is it possible for another thread to be called between the GET_ITER and STORE_FAST?

-- Steven D'Aprano



More information about the Python-Dev mailing list