If I understand the problem statement correctly, youâre not happy with the current one liners:
big_cup = set().union(*data)
big_cap = set(data[0]).intersection(*data[1:])
and you want them rolled into single calls:
big_cup = set.union(*data)
big_cap = set.intersection(*data)
and donât want to write helper functions:
def union_of_iterables(*data):
return set().union(*data)
def intersection_of_iterables(first, /, *rest):
return set(first).intersection(*rest)
Some questions come to mind:
Would people who subclass set() and frozenset() need to alter their code? Is this even possible is the subclass constructor takes an extra argument such as a type converter?
Would collections.abc.Set and collections.abc.MutableSet change as well?
Why not set.difference() as well? That would save:
set(data[0]).difference(*data[1:])
How about set.isdisjoint()? Should it also accept an iterable of iterables?
Should dict.get() accept a list of key/value pairs for the first argument?
That way users can skip the step of creating a dictionary:
dict(iterable).get(key, default)
Should tuple.count() accept a generic iterable so that users wonât need to write:
tuple(iterable).count(obj)?
Personally, I donât think there is enough of a value add to warrant having an unexpected and incongruous API that isnât in harmony with its surroundings. Also, I donât really like the idea of churning an API for something that comes up so rarely â itâs likely that most users wouldnât use this even once in their careers.
That said, there are implicit type conversions I do like. I still support the suggestion to have str.join() automatically convert its inputs to strings. That would address a common task making it both cleaner and faster than existing solutions. That matches want print() already does and it would be harmonious change.