I suspect yielding an empty iterable would be as usable as the current implementation. You're right there are some aspects to the current implementation that seem counter-intuitive. However, if you think of bucket() as a dict of iterables, the way to implement squares_of_odds would be with a 'get' method:

    squares_of_odds = (x*x for x in buckets(a_bunch_of_ints, lambda y: y % 2).get(1))

Where .get would by default return an empty iterable if the key was not encountered. I like that model better because it gives the caller the ability to "assert on missing" or not, just as with a traditional dict.

Then, bisect would `return queues.get(True), queues.get(False)` (I switched the order to match the docstring). I agree that's more readable, and it also occurs to me that the current implementation of bisect may in fact not be correct. It may be returning the resulting queues in an arbitrary order (based on the truth value of the first item in the source iterable). Here explicit is better.