xor operator

Dom Grigonis dom.grigonis at gmail.com
Wed Nov 15 14:00:06 EST 2023


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.grigonis at 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 at python.org <mailto:python-list at 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.
>> |_|_) |                    |
>> | |   | hjp at hjp.at <mailto:hjp at 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>
> 



More information about the Python-list mailing list