In case someone is actually going to execute the code, there is a bug: `set` need to be wrapped in `len` for criteria args.
> On 15 Nov 2023, at 20:13, Dom Grigonis <dom.grigo...@gmail.com> wrote: > > > The specific situation was related to truth values and following out of that > my considerations regarding equivalent of all and any for counting `truths`. > > So one of the specific examples: > class Publisher: > def __init__(self): > self.subscribers = dict() > > def subscribe(self, sub, criteria, agg=all): > self.subscribers[sub] = (criteria, agg) > > def publish(self, msg): > for sub, criteria in self.subscribers.items(): > if criteria(msg): > sub.handle(msg) > > p = Publisher() > p.subscribe(sub, lambda x: all(r > 3 for r in x.ratings)) > > # So what I needed is: > p.subscribe(sub, lambda x: set(r > 3 for r in x.ratings) > 50) > # Note, that elements might not necessarily be bool. > # E.g. at least 51 non-empty pages > p.subscribe(sub, lambda x: set(bool(p) for p in x.pages) > 50) > # So the function: > p.subscribe(sub, lambda x: xor_more_than(x.pages, 50) > # would ideally deal with truth values too. > The question is: can you construct a function? which: > a) performs: lambda x: set(bool(el) for el in iterable) > n > b) is in line with performance of python’s `all` > > Then, as I said the case where one would need `set() == n` is hard to think > of, but it seems fairly probable to need `set() > n` and `set() < n`. > > Regards, > DG > >> On 15 Nov 2023, at 19:16, Peter J. Holzer via Python-list >> <python-list@python.org <mailto:python-list@python.org>> wrote: >> >> On 2023-11-15 12:26:32 +0200, Dom Grigonis wrote: >>> >>> Thank you, >>> >>> >>> test2 = [True] * 100 + [False] * 2 >>> test2i = list(range(100)) >>> >>> %timeit len(set(test2i)) == 1 # 1.6 µs ± 63.6 ns per loop (mean ± std. >>> dev. of 7 runs, 1,000,000 loops each) >>> %timeit all(test2) # 386 ns ± 9.58 ns per loop (mean ± std. >>> dev. of 7 runs, 1,000,000 loops each) >>> >>> test2s = set(test2i) >>> %timeit len(test2s) == 1 # 46.1 ns ± 1.65 ns per loop (mean ± std. >>> dev. of 7 runs, 10,000,000 loops each) >>> >>> If you pre-convert to set it is obviously faster. However, set >>> operation is most likely going to be part of the procedure. In which >>> case it ends up to be significantly slower. >> >> Obviously, if you convert a list to a set just to count the elements >> it's going to be slow. My suggestion was to use the set *instead* of the >> list. I don't know whether that's possible in your situation, because >> you haven't told us anything about it. All I'm suggesting is taking a >> step back and reconsider your choice of data structure. >> >> hp >> -- >> _ | Peter J. Holzer | Story must make more sense than reality. >> |_|_) | | >> | | | h...@hjp.at <mailto:h...@hjp.at> | -- Charles Stross, >> "Creative writing >> __/ | http://www.hjp.at/ <http://www.hjp.at/> | challenge!" >> -- >> https://mail.python.org/mailman/listinfo/python-list >> <https://mail.python.org/mailman/listinfo/python-list> > -- https://mail.python.org/mailman/listinfo/python-list