1

I have a method, which needs to return the result of multiple checks for equality. It is an implementation of the __eq__ method of a class, which represents vocables in my application. Here is the code for the return statement:

return all((
    self.first_language_translations == other.first_language_translations,
    self.first_language_phonetic_scripts == other.first_language_phonetic_scripts,
    self.second_language_translations == other.second_language_translations,
    self.second_language_phonetic_scripts == other.second_language_phonetic_scripts
))

I've tested the runtime of this way of doing it and the other way, using and operators. The and operators are slightly faster, maybe 0.05s. It seems logical, because of having to create a list of those boolean values first and then running a function, which might do more than what the corresponding and operators would have done. However, this is probably going to be executed a lot during my applications runtime.

Now I am wondering, if the usage of all in such a case is a good or a bad practice and if it is worth the slowdown, if it is a good practice. My application is all about vocables and might often need to check, whether a vocable or an identical one is already in a list of vocables. It doesn't need to be super fast and I am thinking this might be micro-optimization, so I'd like to use the best practice for such a situation.

Is this a good usage of the built in all function?

Zelphir Kaltstahl
  • 5,722
  • 10
  • 57
  • 86
  • I don't think this is any clearer than just using `and`. For such a quick operation, you should choose the implementation that is clearest. – rlbond Sep 08 '15 at 23:02
  • 1
    As well as being clearer to a reader/maintainer, using and is almost certainly quicker because as soon as one of the tests is False it will short-circuit the evaluation (i.e. not evaluate the subsequent expressions) because as soon as one is False the overall result must then be False. – DisappointedByUnaccountableMod Sep 08 '15 at 23:07
  • 1
    If the class is basically just a data container, you may want to implement it as a `NamedTuple` instead, which gets you field-based equality comparison for free (among other things). – tzaman Sep 08 '15 at 23:10
  • @tzaman good suggestion, however, I need them to be mutable and the `__eq__` method is not supposed to check all fields for equality, but only some, while others are meta data. – Zelphir Kaltstahl Sep 08 '15 at 23:29

1 Answers1

1

No, that's not a good use of all(), since you have a small, fixed number of comparisons to make, and all() isn't even letting you represent it any more succinctly than you would when using and. Using and is more readable, and you should always put readability first unless you've profiled and performance is actually an issue. That said, using and is indeed a tiny bit faster in the worst case, and even faster on average because it'll short circuit on the first False rather than executing all the comparisons every time.

Cyphase
  • 11,502
  • 2
  • 31
  • 32
  • `all` short-circuits also. See http://stackoverflow.com/questions/17246388/does-python-alllist-use-short-circuit-evaluation – saulspatz Sep 08 '15 at 23:57
  • @saulspatz, `all()` itself does short-circuit, but in this case all four comparisons in the OP's code will be executed to create the tuple that is only then being passed to `all()`. Whereas using `and` will only execute the comparisons until the first `False` is reached. – Cyphase Sep 09 '15 at 07:37
  • Aha. You're correct. I misunderstood your statement. BTW, I often find `all` to be more readable than a `for` loop, but not in this case, of course. – saulspatz Sep 09 '15 at 14:38
  • @saulspatz, oh sure; I often pass generator expressions to `all()`. – Cyphase Sep 09 '15 at 18:30