Live data from Hacker News

Python idiom for taking the single item from a list

blog.garlicsim.org

21–30 of 97 posts

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

#22
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 (…

I agree it's cool that it works on lists and sets and dictionary keys. Upvoted, etc. Just noting that there are many situations where it won't replace the [0].

Also, I don't worry about order on simple equality expressions unless someone asks me to do it a certain way. That's a religious argument and a complete waste of time for me.

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

#23
post #3

Very good idea, I support this and will use it from now on (even though I don't like the (thing,) Python syntax very much), as it's the only way to say that the iterable should only have one element.

The brackets are optional; you can also write

thing, = [stuff]

though some people think that it's less legible since it has a completely different meaning without the comma.

EDIT: you can even play with the whitespace and pretend that ",=" is a list->scalar conversion operator:

x ,= [1]

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

#24
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)

  return reduce(fn, lst)
does the same thing.

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

#25
post #3

Very good idea, I support this and will use it from now on (even though I don't like the (thing,) Python syntax very much), as it's the only way to say that the iterable should only have one element.

The brackets are optional; you can also write thing, = [stuff] though some people think that it's less legible since it has a completely different meaning without the comma. EDIT: you can even play with the whitespace and pretend that ",=" is a list->scalar conversion operator: x ,= [1]

I know about the optional parentheses, but omitting them makes the comma very easy to overlook :/ I do like your fake operator idea, but it seems that it would go against the spirit of python and make it easier at the expense of readability...

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

#28
post #4
post #3

Very good idea, I support this and will use it from now on (even though I don't like the (thing,) Python syntax very much), as it's the only way to say that the iterable should only have one element.

As a commenter there noted, [thing] = stuff works too. I think I like that even better.

Oh, you're very much correct. Let me benchmark that...

There doesn't appear to be any difference in speed between the two. Assigning the result to one variable (totally different to this) is about 6% faster, so this syntax is what I'll use, thank you!

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

#29
post #20

Earlier quoted context omitted.

> 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.

Your comment is interesting at a number of levels. And by interesting, I mean that I can hardly fathom you wrote it:

> Yes. Why is that surprising?

because you called it "tuple unpacking". Furthermore, because in functional languages where this feature comes from you actually unpack tuples, and pattern-matching of other structures is not called "tuple unpacking".

> I've always thought that the tuple referred to by 'tuple unpacking' was the target containing the variables being assigned

That's what the "tuple" is unpacked into, it makes no sense that the name of the pattern would come from there. At best and stretching it, you'd have "into-a-tuple unpacking". Furthermore, you're not actually unpacking into a tuple (even less so in Python 3, `(1, * a)` isn't a valid expression... anywhere that I know of), you're unpacking into free variables. That's the point of unpacking.

> because you frequently unpack things other than tuples.

The only other thing frequently unpacked is a list, and Python's tuples are immutable lists, it does not stretch the imagination that a read-only feature of tuples would work on their mutable cousin as well. As for other structures, in 6 years of Python I'd say I've seen unpacking of arbitrary iterators thrice at best. You do not frequently unpack dicts or iterators.

edit: fucking hell, yc's comment format sucks donkey balls.

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

#30

Proposed style guide: When you want to get the (n+1)th item from a list, do: item = stuff[n] To get the first item, do: item = stuff[0] Unless the list has one element, then do: (item, ) = stuff At least you'll never be accused of consistency.

Not really. The first two are consistent, but the last one is "get the only item and assert that there is only one item to get. If you don't care about the assertion, use [0], as always. I like the latter, because there's added info for the reader ("this should return a one-item iterable").

It's not really inconsistent, because you aren't performing the same operation in the two cases.

Post reply on HN