Python lacks the Axiom of Choice

Python has sets, but lacks the axiom of choice.

If I have a set object or a frozenset object then that object may or may not have members.

If a set has a single member, then I can get that member using set.pop():

chars = {"a", "b", "c"}

if len(chars) == 1:
    print(chars.pop())
else:
    print("[" + "".join(escape(char) for char in sorted(chars)) + "]")

But this has two drawbacks. Firstly, it's destructive: chars is now empty after following the first code path.

Secondly, it doesn't work on frozensets, because you can't modify a frozenset. The only option available to me is:

chars = frozenset({"a", "b", "c"})

if len(chars) == 1:
    print([char for char in chars][0])
else:
    print("[" + "".join(escape(char) for char in sorted(chars)) + "]")

which is just disgusting. Wouldn't it be much prettier if Python simply supported the axiom of choice?

chars = frozenset({"a", "b", "c"})

if len(chars) == 1:
    print(chars.choose())
else:
    print("[" + "".join(escape(char) for char in sorted(chars)) + "]")

My suggested method is frozenset.choose(). This method would return, but not remove, an element from the frozenset. A KeyError would arise if the frozenset is empty.

I assume that set would inherit the method, or at least implement it identically.

What about when called on frozensets with more than one element?

The element returned would explicitly be "no element in particular", not necessarily the "first" element according to any kind of ordering of the frozenset. There would be no guarantee of consistent results if choose() were called multiple times on the same frozenset or on identical frozensets, but neither would choose() be expected to iterate over a frozenset's elements if called repeatedly.

Update

Several people suggested some alternate, less disgusting formations:

print(list(chars)[0])
print(list(chars).pop()) # is destructive, but only to list(chars)
print(next(iter(chars)))

All of these are preferable to [char for char in chars][0], but I think most people would agree with me that, still, none of them quite hit the spot. The Zen of Python states that "There should be one-- and preferably only one --obvious way to do it", whereas these methods are all of varying, approximately equal non-obviousness. I maintain that a simple frozenset.choose() method would stand head and shoulders above these others as the obvious way to accomplish this task.

Back to Code
Back to Things Of Interest

Facebook Twitter Reddit Email Hacker News StumbleUpon