On 13 Nov 2023, at 15:16, Dom Grigonis via Python-list <python-list@python.org> wrote:
I think it could be useful to have `xor` builtin, which has API similar to the one of `any` and `all`.
On 13 Nov 2023, at 19:42, Barry <barry@barrys-emacs.org> wrote:
On 13 Nov 2023, at 15:16, Dom Grigonis via Python-list <python-list@python.org> wrote:
I think it could be useful to have `xor` builtin, which has API similar to the one of `any` and `all`.
I do not understand how xor(iterator) works.
I thought xor takes exactly 2 args.
I also do not understand how xor can be short circuited.
For AND or OR only looking at the first arg works.
But that does not work for xor right?
Barry
On 13 Nov 2023, at 17:48, Dom Grigonis <dom.grigonis@gmail.com> wrote:
Short circuiting happens, when:
xor([True, True, False, False], n=1)
At index 1 it is clear that the answer is false.
I do not understand how xor(iterator) works.
I thought xor takes exactly 2 args.
I also do not understand how xor can be short circuited.
On 13 Nov 2023, at 17:48, Dom Grigonis <dom.grigonis@gmail.com> wrote:
Short circuiting happens, when:
xor([True, True, False, False], n=1)
At index 1 it is clear that the answer is false.
Can you share an example with 4 values that is true?
And explain why it is xor.
... return sum( map( bool, iterable ) ) == ndef xor( iterable, n = 1 ):
... for intermediate in itertools.accumulate( iterable, (lambda x, y: x + bool(y)), initial = 0 ):def xor_ss( iterable, n = 1 ):
On 13 Nov 2023, at 17:48, Dom Grigonis <dom.grigonis@gmail.com> wrote:
Short circuiting happens, when:
xor([True, True, False, False], n=1)
At index 1 it is clear that the answer is false.
Can you share an example with 4 values that is true?
And explain why it is xor.
Barry
--
https://mail.python.org/mailman/listinfo/python-list
Barry <barry@barrys-emacs.org> writes:
I do not understand how xor(iterator) works.
I thought xor takes exactly 2 args.
See
https://mathworld.wolfram.com/XOR.html
for some background (I was not aware of any generalizations for more
than 2 arguments either).
On 13 Nov 2023, at 23:03, Barry <barry@barrys-emacs.org> wrote:
On 13 Nov 2023, at 17:48, Dom Grigonis <dom.grigonis@gmail.com> wrote:
Short circuiting happens, when:
xor([True, True, False, False], n=1)
At index 1 it is clear that the answer is false.
Can you share an example with 4 values that is true?
And explain why it is xor.
Barry
On 13 Nov 2023, at 23:20, Michael Speer <knomenet@gmail.com> wrote:
I don't think an exclusive-or/truthy-entries-count-checker needs to be a builtin by any stretch.
... return sum( map( bool, iterable ) ) == ndef xor( iterable, n = 1 ):
Or if you insist on short circuiting:
... for intermediate in itertools.accumulate( iterable, (lambda x, y: x + bool(y)), initial = 0 ):def xor_ss( iterable, n = 1 ):
... if intermediate > n:
... return False
... return intermediate == n
On Mon, Nov 13, 2023 at 4:05 PM Barry via Python-list <python-list@python.org <mailto:python-list@python.org>> wrote:
On 13 Nov 2023, at 17:48, Dom Grigonis <dom.grigonis@gmail.com <mailto:dom.grigonis@gmail.com>> wrote:
Short circuiting happens, when:
xor([True, True, False, False], n=1)
At index 1 it is clear that the answer is false.
Can you share an example with 4 values that is true?
And explain why it is xor.
Barry
--
https://mail.python.org/mailman/listinfo/python-list <https://mail.python.org/mailman/listinfo/python-list>
Hi All,
I think it could be useful to have `xor` builtin, which has API similar to the one of `any` and `all`.
* Also, it could have optional second argument `n=1`, which
* indicates how many positives indicates `True` return. For
* complete flexibility 3rd argument could indicate if `the number`
* is equal, greater, less, ... than `n`
I am not asking. Just inquiring if the function that I described could be useful for more people.
Which is: a function with API that of `all` and `any` and returns `True` if specified number of elements is True.
It is not a generalised `xor` in strict programatic space. I.e. NOT bitwise xor applied to many bits.
This is more in line with cases that `any` and `all` builtins are used.
On 14 Nov 2023, at 00:51, Grant Edwards via Python-list <python-list@python.org> wrote:
On 2023-11-13, Dom Grigonis via Python-list <python-list@python.org> wrote:
Hi All,
I think it could be useful to have `xor` builtin, which has API similar to the one of `any` and `all`.
* Also, it could have optional second argument `n=1`, which
* indicates how many positives indicates `True` return. For
* complete flexibility 3rd argument could indicate if `the number`
* is equal, greater, less, ... than `n`
I would expect "xor" to return true if there are an odd number of
trues, and false if there are an even number of trues. It's not clear
to me what you're asking for.
--
https://mail.python.org/mailman/listinfo/python-list
On 14 Nov 2023, at 01:12, Chris Angelico via Python-list <python-list@python.org> wrote:
On Tue, 14 Nov 2023 at 10:00, Dom Grigonis via Python-list <python-list@python.org> wrote:
I am not asking. Just inquiring if the function that I described could be useful for more people.
Which is: a function with API that of `all` and `any` and returns `True` if specified number of elements is True.
It is not a generalised `xor` in strict programatic space. I.e. NOT bitwise xor applied to many bits.
This is more in line with cases that `any` and `all` builtins are used.
A generalization of XOR is exactly what Grant and I said, though: a
parity check. See for example:
https://en.wikipedia.org/wiki/Exclusive_or https://reference.wolfram.com/language/ref/Xor.html
It tells you whether you have an odd or even number of true values.
Now, if you want something that short-circuits a counting function,
that's definitely doable, but it's a sum-and-compare, not xor. Also,
it's quite specialized so it's unlikely to end up in the stdlib.
ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
AFAICT, it's not nothing at all to do with 'xor' in any sense.
On 2023-11-13, Dom Grigonis via Python-list <python-list@python.org>
wrote:
I am not asking. Just inquiring if the function that I described
could be useful for more people.
Which is: a function with API that of `all` and `any` and returns
`True` if specified number of elements is True.
I've got no objection to a function that counts True objects returned
by an iterator and returns True IFF count == <N>.
I've got no objection to a function that counts True objects returned
by an iterator and returns True IFF count >= <N>.
I've got no objection if that latter function short-circuits by
stopping the iteration and returning True when it has seen <N> true
objects.
I don't recall ever having a need for such a function in the 25 years
I've been writing Python code, but I'm not going to claim that nobody
else has a need for such a function.
I would object to that being called 'xor', and would fight to the
death (yes, I'm being hyperbolic) the addition of a builtin with the
name 'xor' that does what you describe.
It is not a generalised `xor` in strict programatic space.
AFAICT, it's not nothing at all to do with 'xor' in any sense.
I.e. NOT bitwise xor applied to many bits. This is more in line
with cases that `any` and `all` builtins are used.
Except the 'any' and 'all' builtins are _exactly_ the same as bitwise
or and and applided to many bits. To do something "in line" with that
using the 'xor' operator would return True for an odd number of True
values and False for an even Number of True values.
--
Grant
--
https://mail.python.org/mailman/listinfo/python-list
Except the 'any' and 'all' builtins are _exactly_ the same as bitwise
or and and applided to many bits. To do something "in line" with that
using the 'xor' operator would return True for an odd number of True
values and False for an even Number of True values.
I am not arguing that it is a generalised xor.
I don’t want anything, I am just gauging if it is specialised or if there is a need for it. So just thought could suggest it as I have encountered such need several times already.
It is fairly clear by now that it is not a common one given it took some time to even convey what I mean. Bad naming didn’t help ofc, but if it was something that is needed I think it would have clicked much faster.
I am not asking. Just inquiring if the function that I described
could be useful for more people.
Which is: a function with API that of `all` and `any` and returns
`True` if specified number of elements is True.
It is not a generalised `xor` in strict programatic space.
I.e. NOT bitwise xor applied to many bits. This is more in line
with cases that `any` and `all` builtins are used.
Except the 'any' and 'all' builtins are _exactly_ the same as bitwise
or and and applided to many bits. To do something "in line" with that
using the 'xor' operator would return True for an odd number of True
values and False for an even Number of True values.
Fair point.
Have you ever encountered the need for xor for many bits (the one that I am NOT referring to)? Would be interested in what sort of case it could be useful.
On 14 Nov 2023, at 02:33, Mats Wichmann via Python-list <python-list@python.org> wrote:many topics; there are millions of people using Python. Still, the folks here like to think they're at least somewhat representative :)
On 11/13/23 16:24, Dom Grigonis via Python-list wrote:
I am not arguing that it is a generalised xor.
I don’t want anything, I am just gauging if it is specialised or if there is a need for it. So just thought could suggest it as I have encountered such need several times already.
It is fairly clear by now that it is not a common one given it took some time to even convey what I mean. Bad naming didn’t help ofc, but if it was something that is needed I think it would have clicked much faster.
There are things that If You Need Them You Know, and If You Do Not You Do Not Understand - and you seem to have found one. The problem is that forums like this are not a statistically great sampling mechanism - a few dozen people, perhaps, chime in on
Hardware and software people may have somewhat different views of xor, so *maybe* the topic title added a bit to the muddle. To me (one of those millions), any/all falsy, any/all truthy have some interest, and Python does provide those. Once you getinto How Many True question - whether that's the odd-is-true, even-is-false model, or the bail-after-X-truthy-values model, it's not terribly interesting to me: once it gets more complex than an all/any decision, I need to check for particular
--
https://mail.python.org/mailman/listinfo/python-list
Hardware and software people may have somewhat different views of xor
As I am here, I will dare to ask if there is no way that `sign` function is going to be added to `math` or `builtins`.
Here's a couple of excellent videos on error correction, and you'll
see XOR showing up as a crucial feature:
https://www.youtube.com/watch?v=X8jsijhllIA https://www.youtube.com/watch?v=h0jloehRKas
Except the 'any' and 'all' builtins are _exactly_ the same as bitwise
or and and applided to many bits. To do something "in line" with that
using the 'xor' operator would return True for an odd number of True
values and False for an even Number of True values.
Fair point.
Have you ever encountered the need for xor for many bits (the one
that I am NOT referring to)? Would be interested in what sort of
case it could be useful.
Except the 'any' and 'all' builtins are _exactly_ the same as bitwise
or and and applided to many bits. To do something "in line" with that
using the 'xor' operator would return True for an odd number of True
values and False for an even Number of True values.
Fair point.
Have you ever encountered the need for xor for many bits (the one
that I am NOT referring to)? Would be interested in what sort of
case it could be useful.
Benchmarks:
test1 = [False] * 100 + [True] * 2
test2 = [True] * 100 + [False] * 2
TIMER.repeat([
lambda: xor(test1), # 0.0168
lambda: xor(test2), # 0.0172
lambda: xor_ss(test1), # 0.1392
lambda: xor_ss(test2), # 0.0084
lambda: xor_new(test1), # 0.0116
lambda: xor_new(test2), # 0.0074
lambda: all(test1), # 0.0016
lambda: all(test2) # 0.0046
])
Your first function is fairly slow.
Second one deals with short-circuiting, but is super slow on full search.
`xor_new` is the best what I could achieve using python builtins.
But builtin `all` has the best performance.
On 15 Nov 2023, at 02:34, Peter J. Holzer via Python-list <python-list@python.org> wrote:
On 2023-11-14 00:11:30 +0200, Dom Grigonis via Python-list wrote:
Benchmarks:
test1 = [False] * 100 + [True] * 2
test2 = [True] * 100 + [False] * 2
TIMER.repeat([
lambda: xor(test1), # 0.0168
lambda: xor(test2), # 0.0172
lambda: xor_ss(test1), # 0.1392
lambda: xor_ss(test2), # 0.0084
lambda: xor_new(test1), # 0.0116
lambda: xor_new(test2), # 0.0074
lambda: all(test1), # 0.0016
lambda: all(test2) # 0.0046
])
Your first function is fairly slow.
Second one deals with short-circuiting, but is super slow on full search.
`xor_new` is the best what I could achieve using python builtins.
But builtin `all` has the best performance.
One question worth asking is if a list of bool is the best data
structure for the job. This is essentially a bitmap, and a bitmap is equivalent to a set of integers. len(s) == 1 is also a fairly quick
operation if s is small. On my system, len(test1s) == 1 (where test1s is {100, 101}) is about as fast as all(test1) and len(test2s) == 1 (where
test2s is set(range(100))) is about twice as fast as all(test2).
If you are willing to stray from the standard library, you could e.g.
use pyroaring instead of sets: This is about as fast as all(test1)
whether there are two bits set or a hundred.
hp
--
_ | Peter J. Holzer | Story must make more sense than reality.
|_|_) | |
| | | hjp@hjp.at <mailto:hjp@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>
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.
On 15 Nov 2023, at 19:16, Peter J. Holzer via Python-list <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.
|_|_) | |
| | | hjp@hjp.at | -- Charles Stross, "Creative writing
__/ | http://www.hjp.at/ | challenge!"
--
https://mail.python.org/mailman/listinfo/python-list
On 15 Nov 2023, at 20:13, Dom Grigonis <dom.grigonis@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.
|_|_) | |
| | | hjp@hjp.at <mailto:hjp@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>
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 546 |
Nodes: | 16 (2 / 14) |
Uptime: | 14:09:20 |
Calls: | 10,389 |
Files: | 14,061 |
Messages: | 6,416,893 |