Live data from Hacker News

Python idiom for taking the single item from a list

blog.garlicsim.org

51–60 of 97 posts

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

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

It is a good thing if code is readable by people who only know the language a little, only know similar languages, or have not used the language for years.

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

#52
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?

"There should be one-- and preferably only one --obvious way to do it."

A couple of things:

1) The key word is obvious. There are oftentimes less obvious ways to do things that may be better for whatever reason.

2) It's not really reasonable to expect that there can only be one way to do everything.

What it really means is that (for instance) Python only allows one way to denote where a code block begins and ends (via indentation) while Ruby allows you to use curly brackets and begin/end. Nor does it have an unless statement that is equivalent to "if not"

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

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

It is a good thing if code is readable by people who only know the language a little, only know similar languages, or have not used the language for years.

It is a good thing, but it isn't the highest good. It doesn't make sense to avoid useful basic features simply because they aren't immediately obvious to a novice in the language.

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

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

That fails for sets and other non-list iterables. It would have to be something like:

  def get_single(l):
      i = iter(l)
      val = i.next()
      try:
          i.next() # expected to throw exception for one-element iterable
      except StopIteration:
          return val
      raise AssertionError('More than one object')
Eww.

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

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

Lists use (not infrequently) logic like the following;

  If one element
    do this one element thing
  else
    do this more than one element thing

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

#56

Earlier quoted context omitted.

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…

The point of the above post was to say "this is nice syntax, and it isn't ten times slower, so it's good on that front too", not to say "use that because it's 6% faster". I'm never going to write this in a tight loop anyway, and even if I did, I'd benchmark the entire piece of code, not just this line.

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

#57
post #50

Earlier quoted context omitted.

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.

No doubt! But since we're on the subject of "how to make code like this better" it seems appropriate to discuss what's really wrong with the code, rather than just what sort of duct tape style guidelines we can use to patch over its flaws :)

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

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

> assert l and len(l) == 1

This is redundant: if a list's length is 1, then it's true in a boolean context.

Also, please stop naming your lists 'l'. On a vast array of fonts, it differs only in a few pixels from '1'. Use "L" instead :)

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

#59
post #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.

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

This is an argument against using functions at all. If it works against get_single, it works against all functions.

That is to say, it doesn't work at all.

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

#60
post #50

Earlier quoted context omitted.

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

No doubt! But since we're on the subject of "how to make code like this better" it seems appropriate to discuss what's really wrong with the code, rather than just what sort of duct tape style guidelines we can use to patch over its flaws :)

Very often we can't change the API (standard library or such). Should we not change our code to address the issue as best we can?
Post reply on HN