Live data from Hacker News

Python idiom for taking the single item from a list

blog.garlicsim.org

11–20 of 97 posts

Re: Python idiom for taking the single item from a list

#12

So we have so if I was wrong in my original assumption that stuff has exactly one element, Python will shout at me before this will manifest itself as a hard-to-find bug someplace else in the program. and then later on, This method works even when stuff is a set or any other kind of collection. stuff[0] wouldn’t work on a set because set doesn’t support access by index number. The second argument is basically in favo…

Duck-typing means you don't assume that the object is from a certain type; Instead you assume that it's got the interfaces you need. (Either `.__iter__()` or `.__getitem__(0)` in this case.)

`.__iter__()` is a more general and common interface than `.__getitem__(0)`, so it's preferable to assume that the object implements the former rather than the latter.

But sometimes you do want to assume stuff about your object. In this case we want to assume that the list has exactly one item, and we want our code to break immediately if it isn't true.

Re: Python idiom for taking the single item from a list

#14
post #8

My problem is that exact situation almost never comes up. Usually, I want to use the item in the list directly in an expression, not assign it to another variable first. For example: if 1==len(lst): return lst[0] else: return reduce(fn, lst) I don't really want to have to do: if 1==len(lst): (single,)=lst return single else: return reduce(fn, lst)

I see what you mean. In this case it's indeed questionable whether this idiom would improve the code. The only improvement I can offer for this code is to fix the Yoda conditions :)

Re: Python idiom for taking the single item from a list

#15

Single-element tuple unpacking? I've never found a case where I knew there would only be one element in a list, but I do use tuple unpacking all of the time. Pretty cool I guess; didn't know it wasn't a common idiom. Good to know. Thanks for sharing. :)

http://docs.python.org/library/struct.html#struct.unpack

"""The result is a tuple even if it contains exactly one item."""

I run into this constantly using struct.unpack(), and I find the author's idiom to be ideal way to handle this. I will use this from now on.

Re: Python idiom for taking the single item from a list

#16

So we have so if I was wrong in my original assumption that stuff has exactly one element, Python will shout at me before this will manifest itself as a hard-to-find bug someplace else in the program. and then later on, This method works even when stuff is a set or any other kind of collection. stuff[0] wouldn’t work on a set because set doesn’t support access by index number. The second argument is basically in favo…

> But what about the first argument? Couldn't you make the case that the pythonic way of handling it is to only care about if the object responds to __getitem__(0)?

Mmm no? Here, what he cares about is that it's a single-element collection, he doesn't just want the collection's first item. If he did, foo[0] would do a better job.

So the object responding to __getitem__(0) is not a sufficient condition.

In fact, it's entirely wrong as sets do _not_ implement __getitem__. Worse, __getitem__(0) does a very different thing than unpacking on a dict. Unpacking is more ducky than __getitem__ for this case, because it expresses the following: the right-hand is a single-element iterable. Any iterable will work as long as it only has a single item, it doesn't have to be a sequence, a mapping, or even a collection (generators or callable_iterators will work just as well)

Re: Python idiom for taking the single item from a list

#17
post #10

I think this style has one great drawback: it requires deeper knowledge of Python then the 'usual' thing = stuff[0].

If someone's knowledge of Python is so shallow that they can't handle tuple unpacking, they should learn more Python. It's one of the basic foundations of the language, and it's hardly a difficult concept.

Re: Python idiom for taking the single item from a list

#18
post #8

My problem is that exact situation almost never comes up. Usually, I want to use the item in the list directly in an expression, not assign it to another variable first. For example: if 1==len(lst): return lst[0] else: return reduce(fn, lst) I don't really want to have to do: if 1==len(lst): (single,)=lst return single else: return reduce(fn, lst)

That's very different than OP's piece of code: you're not trying to assert that the iterable yields a single element, you already know it.

Furthermore, OP's assertion-unpacking will work not just on lists, but also on dicts (will return the only key, not the only value, and the key doesn't have to be ``0``), on sets (which don't implement __getitem__ at all), on arbitrary collections and even on arbitrary iterables (including callable_iterator and generators)

Also, please don't put the constant on the left-hand of a comparison in Python, it's useless and ugly.

Re: Python idiom for taking the single item from a list

#19
post #17
post #10

I think this style has one great drawback: it requires deeper knowledge of Python then the 'usual' thing = stuff[0].

If someone's knowledge of Python is so shallow that they can't handle tuple unpacking, they should learn more Python. It's one of the basic foundations of the language, and it's hardly a difficult concept.

> If someone's knowledge of Python is so shallow that they can't handle tuple unpacking

Did you know that "tuple unpacking" actually works on arbitrary iterables (in fact, the relevant function in Python's C code is called ``unpack_iterable``)?

    >>> def f(): yield 3
    ... 
    >>> b, = f()
    >>> b
    3
you should be careful with such declarations.

Re: Python idiom for taking the single item from a list

#20
post #17

Earlier quoted context omitted.

If someone's knowledge of Python is so shallow that they can't handle tuple unpacking, they should learn more Python. It's one of the basic foundations of the language, and it's hardly a difficult concept.

> If someone's knowledge of Python is so shallow that they can't handle tuple unpacking Did you know that "tuple unpacking" actually works on arbitrary iterables (in fact, the relevant function in Python's C code is called ``unpack_iterable``)? >>> def f(): yield 3 ... >>> b, = f() >>> b 3 you should be careful with such declarations.

Yes. Why is that surprising? f is a generator, generators are iterables, iterables can be unpacked. I've always thought that the tuple referred to by 'tuple unpacking' was the target containing the variables being assigned, rather than the thing being unpacked, because you frequently unpack things other than tuples.
Post reply on HN