Live data from Hacker News

Python idiom for taking the single item from a list

blog.garlicsim.org

41–50 of 97 posts

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

#41
post #20

Earlier quoted context omitted.

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 't…

Unpacking applies to iterables. That seems obvious and easy, but the feature is commonly called "tuple unpacking" in the Python world despite the fact that more than tuples can be unpacked. I resolve the apparent conflict by thinking of the term as referring to the most common form of the literal on the left side of the statement, the same syntax as a tuple. If that's not the actual origin, fine, you win the pissing match. But where the name came from has zero bearing on the actual behavior of the language feature, and the point remains that the language feature is simple, consistent, and basic enough that if you don't understand it when you see it, you need to learn the language better.

The only other thing frequently unpacked is a list

Which isn't a tuple. You're the one trying to be pedantic, but you want to ding me for making this distinction?

it does not stretch the imagination that a read-only feature of tuples would work on their mutable cousin as well.

I agree, it doesn't. I don't see how it stretches the imagination that it works on general iterables, either.

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

#42
post #35

The real solution is not to arbitrarily encode your types as lists of exactly one item. If you find yourself passing around such lists with enough regularity that you feel the need to develop an idiom for deconstructing them, you're doing something wrong.

More often than not you are receiving a list from some function, not constructing it manually. As an example: Say you have a GUI widget that can contain many entries, and you call `widget.get_entries()` which returns a list with all the entries. But if you know there must be only one entry, you can do `(entry,) = widget.get_entries()`.

Then it should make a method which returns its known, sole entry. Returning a list of entries from a widget which will always contain only one entry is the logical equivalent to converting a function return value to a string and then expecting the client to convert it back from a string. That is to say, it's necessary in a general case (e.g., a Widget super class) but should not be exposed that way in some specific cases (e.g., your subclass wherein you know there will always be one entry).

In reality, you shouldn't be mucking with the entries of a widget at all; you should tell the widget what to do and it should adjust its entries as necessary). Demeter's law and all.

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

#43
post #2

Excellent. That one belongs in any Python style guide. Though technically it's not a style, it does lead to better readability, and reduces the propensity for unforseen consequences.

The reason it's not in the Python style guide is because it's a symptom of other problems in code. Lists are for holding multiple values of the same type. If you know that a list will always have one and only one value, it's not conceptually a list, it's some other type that's been encoded into a list for some reason, and you should fix that conceptual mismatch rather than papering over the issue with a style idiom.

We also commonly use tuples as light-weight types (a kind of heterogeneous collection).

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

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

Isn't "there's more than one way to do it" why Python programmers hate Perl?

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

#45
post #4

Earlier quoted context omitted.

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!

Assigning the result to one variable (totally different to this) is about 6% faster, so this syntax is what I'll use, thank you!

On your exact machine with your exact version of Python, today.

Please don't let microbenchmarks dictate what code you write. If you need a 6% performance gain in a microbenchmark, you've chosen the wrong language to use. Python is about readability and maintainability, not syntax hacks to make some benchmark slightly faster.

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

#46
post #37

I prefer array.single(), I think it's a rare enough use-case that spelling out what you are doing is worthwhile.

Are you talking about another language?

1) In python, arrays and lists are two very different things.

2) Neither the array module nor the array class have a single function.

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

#47
Personally, I think this is a bit on the "clever" side. Plus, the error message you get isn't as easy to understand as if you used an assert statement. I'd probably just do something like this:

    def get_single(l):
        assert l and len(l) == 1
        return l[0]
Then you get the best of both worlds: readability and a concise one-liner.

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

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

Isn't "there's more than one way to do it" why Python programmers hate Perl?

This is the one way to do it. masklinn has cousin comment that does a good job of explaining why: http://news.ycombinator.com/item?id=1732575, and others have made some good points questioning whether you'd ever actually want to do this particular "it" in the first place.

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

#49
post #47

Personally, I think this is a bit on the "clever" side. Plus, the error message you get isn't as easy to understand as if you used an assert statement. I'd probably just do something like this: def get_single(l): assert l and len(l) == 1 return l[0] Then you get the best of both worlds: readability and a concise one-liner.

I'd avoid doing this, because people who'll read your code would have to check themselves what the `get_single` function does.

Also, the performance here is probably much worse. (Although in many cases it would not matter.)

But that's just my opinion, your suggestion is legitimate.

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

#50
post #35

Earlier quoted context omitted.

More often than not you are receiving a list from some function, not constructing it manually. As an example: Say you have a GUI widget that can contain many entries, and you call `widget.get_entries()` which returns a list with all the entries. But if you know there must be only one entry, you can do `(entry,) = widget.get_entries()`.

Then it should make a method which returns its known, sole entry. Returning a list of entries from a widget which will always contain only one entry is the logical equivalent to converting a function return value to a string and then expecting the client to convert it back from a string. That is to say, it's necessary in a general case (e.g., a Widget super class) but should not be exposed that way in some specific c…

I notice a lot of "shoulds" in this comment. Unfortunately, what should be and what is aren't always the same thing.
Post reply on HN