4 ms·
The problem isn't with all([]) -> True, the problem is the if [] -> False. [] exists. It happens to be empty, but it is neither a False nor a None. Therefore
by michaelteter 3y ago
The problem isn't with all([]) -> True, the problem is the if [] -> False.
[] exists. It happens to be empty, but it is neither a False nor a None. Therefore it should be a True if applying truthiness to it. IMO, any expression which does not result in an actual False or None should be judged as True.
- edit -
On second thought, all([]) -> True is also a poor choice, same in Ruby. The idea of judging an empty collection as having all items being any value is flawed, since there are no items to measure. It is on par with 1 / 0.
This is fun: in both Ruby and Python...
[].all? -> true
all([]) -> True
[].any? -> false
any([]) -> False
So both languages agree that all elements of any empty collection are true, but if you ask them if any of the elements are true, they deny it. So they are all true while also not having any true elements.
- x3n0ph3n3 3y agoThat's exactly how Ruby behaves.
- michaelteter 3y agoRuby and Python agree on the all/any functions, but they disagree on the if. And in the "if", I think the Ruby result is better.
- earthboundkid 3y agoJavaScript thinks empty arrays are true and it’s annoying because you have to write if (a.length) instead of if (a).
- kstrauser 3y agoI disagree. An empty string is False. Any empty set is False. An empty dict is False. Basically, in Python emptiness implies falseness. This has practical benefits: users = database.fetch_users() if not users: print("Didn't find anyone.") and name = input() if not name: print("You didn't enter a name.") Of course you could work around those like `if len(users) == 0` or `if not len(users)` or `if name != ""`, but each of those is uglier. `if not users` translates very nicely to English: "if there are not any users...". I'm glad Python defined `bool(list)` that way.
- robot_no_421 3y agoI'm a Python dev who uses this feature frequently. But the more I use Python (and the more I use Rust in my spare time), the more I realize that I use it only because it's what Python expects me to do. If it was up to me I'd much rather use if my_container.empty(): # do stuff than if not my_container: # do stuff The second implementation behaves the same if either my_container is None or if my_container is empty (or if my_container is 0 or ""...), whereas the first implementation allows me to handle those cases differently. The first implementation is also more explicit and easier to understand on a first read. It's also easier to debug. Is users supposed to be None in your example? Possibly, but your code doesn't give me any hints. Is my_container supposed to be None in my example? Probably not based on the way I explicitly used the .empty() method.
- kstrauser 3y agoPython’s type annotations carry the same information, but explicitly. If fetch_users() returns a list of users, you know exactly what “users” is and whether it can be None. Really, though, list.empty() is canonically spelled “not list” in Python. That’s the idiom to learn, read, and write.
- Delk 3y ago> The idea of judging an empty collection as having all items being any value is flawed, since there are no items to measure. It is on par with 1 / 0. Not really. Those Python functions follow definitions from set theory and predicate logic, and in predicate logic e.g. "for all x, P(x)" is defined as being true if there are no x. The reason for it being defined that way in mathematics is that it actually leads to consistent rules and definitions without the need to define lots of special cases, even if some of those definitions aren't how most people would use some of the same words in everyday language. Similarly, the reason division by zero is considered undefined instead of e.g. equaling infinity is that if it were not considering undefined, that would lead to inconsistency. If we had 1 / 0 = a, with any valid result a, that would mean a * 0 would need to equal 1. Programming languages could of course define their APIs to follow some other (hopefully internally consistent) logic, and I guess you could consider mathematical definitions based on predicate logic or set theory as being a somewhat arbitrary choice. But I disagree that the definition used in Python is on par with division by zero.