In python, there is such a feature - True and False can be added, subtracted, etc
Are there any examples where this can be useful?
Is there any real benefit from this feature, for example, when:
- it increases productivity
- it makes the code more concise (without losing speed) etc
2 Answers 2
While in most cases it would just be confusing and completely unwarranted to (ab)use this functionality, I'd argue that there are a few cases that are exceptions.
One example would be counting. True casts to 1, so you can count the number of elements that pass some criteria in this fashion, while remaining concise and readable. An example of this would be:
valid_elements = sum(is_valid(element) for element in iterable)
As mentioned in the comments, this could be accomplished via:
valid_elements = list(map(is_valid, iterable)).count(True)
but to use .count(...), the object must be a list, which imposes a linear space complexity (iterable may have been a constant space generator for all we know).
Another case where this functionality might be usable is as a play on the ternary operator for sequences, where you either want the sequence or an empty sequence depending on the value. Say you want to return the resulting list if a condition holds, otherwise an empty list:
return result_list * return_empty
or if you are doing a conditional string concatentation
result = str1 + str2 * do_concatenate
of course, both of these could be solved by using python's ternary operator:
return [] if return_empty else result_list
...
result = str1 + str2 if do_concatenate else str1
The point being, this behavior does provide other options in a few scenarios that isn't all too unreasonable. Its just a matter of using your best judgement as to whether it'll cause confusion for future readers (yourself included).
4 Comments
.count(), the iterable must be made into a list, which means that it must be stored entirely in memory at once. However, what if iterable was range(1000000). Range only takes constant space, generating the next element as its requested. By transforming this into a list, suddenly we need O(n) space to store it.range(1000000) is perhaps a bad example to illustrate your point. But yes, it could be a generator function that generates 1000000 bool values, of which we are interested in counting the Trues. I don't see any documentation that says sum won't do dumb things like assembling all the elements and then summing them up. But yeah, I guess it's a safe assumption to make.range(...) (where elements are then passed to is_valid(...)).I would avoid it at all cost. It is confusing and goes against typing. Python being permissive does not mean you should do it ...
2 Comments
bool is actually a subclass of int
valid_elements = sum(is_valid(element) for element in iterable).count(). This of course imposes a linear space complexity on something that may have even been constant (if it were a generator or something), but is doable.str1 + str2 * include_str2boolis actually a subclass ofint