Aaron Meurer added the comment:
I can't believe this issue was closed. Why can't Counter.__lt__(self, other)
just be all(self[i] < other[i] for i in self)?
Just because Counter supports weird stuff shouldn't bill it out. To follow that
logic, we should also remove Counter.subtract
>>>
Ram Rachum added the comment:
Hi everyone,
Just wanted to follow up here that I've created my own dedicated bag class.
Documentation: https://combi.readthedocs.org/en/stable/bags.html
Install using `pip install combi`
It's packed with features. There are a ton of arithmetic operations
Changes by Raymond Hettinger raymond.hettin...@gmail.com:
--
assignee: - rhettinger
___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue22515
___
___
Raymond Hettinger added the comment:
I suggest implementing `Counter.__lt__` which will be a
partial order, similarly to `set.__lt__`.
This would be reasonable if the counter were a strict stand-alone multiset or
bag; however, the core design is much looser than that (supporting negative
Saimadhav Heblikar added the comment:
I mentioned my wording for the comment about lesser than partial ordering using
the code review tool.
In the attached patch(based on issue22515.stoneleaf.patch.01), I have added
test for the case when the other object is not a mapping.
I have also tried
Ram Rachum added the comment:
I don't really understand the refactoring. For example why is `len(self) =
len(other)` needed? For which case? Note that `len` would also catch keys with
`0` value which shouldn't have an effect.
--
___
Python tracker
Serhiy Storchaka added the comment:
There are some properties of set comparison:
(a b) == (a = b and a != b)
(a = b) == (a b or a == b)
(a = b and b = a) == (a == b)
(a b and b a) == False
(a = b) == (a - b == set())
if (a = b and b = c) then (a = c)
(a = b and a = c) == (a = (b c))
(a = c
Ram Rachum added the comment:
There are some properties of set comparison:
(a b) == (a = b and a != b)
I don't think so, because counter equality is based on dict equality so it
doesn't ignore zero values.
(a = b) == (a b or a == b)
No, ditto.
(a = b and b = a) == (a == b)
No,
Changes by Mark Dickinson dicki...@gmail.com:
--
nosy: +mark.dickinson
___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue22515
___
___
Steven D'Aprano added the comment:
On Sat, Oct 04, 2014 at 07:57:16AM +, Serhiy Storchaka wrote:
There are some properties of set comparison:
(a b) == (a = b and a != b)
(a = b) == (a b or a == b)
(a = b and b = a) == (a == b)
(a b and b a) == False
(a = b) == (a - b == set())
Serhiy Storchaka added the comment:
At least this condition is false for current implementation:
(a b and b a) == False
Example: a = Counter({'a': -1}), b = Counter({'b': -1}).
--
___
Python tracker rep...@bugs.python.org
Steven D'Aprano added the comment:
On Sat, Oct 04, 2014 at 08:38:17AM +, Ram Rachum wrote:
Ram Rachum added the comment:
There are some properties of set comparison:
(a b) == (a = b and a != b)
I don't think so, because counter equality is based on dict equality so it
Antoine Pitrou added the comment:
Just because something is discussed doesn't mean it needs a PEP.
Also, see http://bugs.python.org/issue22515#msg227852
--
___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue22515
Ram Rachum added the comment:
I see that in my implementation for __lt__ and __gt__ I forgot to check whether
the other counter has elements that this counter doesn't, which could flip
`found_strict_difference`.
--
___
Python tracker
Steven D'Aprano added the comment:
On Sat, Oct 04, 2014 at 10:43:02AM +, Antoine Pitrou wrote:
Just because something is discussed doesn't mean it needs a PEP.
I know that in general discussions do not need a PEP, but we seem to be
rushing awfully fast into writing code before we even
Antoine Pitrou added the comment:
Le 04/10/2014 17:24, Steven D'Aprano a écrit :
I know that in general discussions do not need a PEP, but we seem to be
rushing awfully fast into writing code before we even know what the code
is supposed to do.
Writing a patch is useful practice because
Ram Rachum added the comment:
Hi everybody,
I agree we have a mess on our hands, with lots of cases where comparison is
weird. To be honest I've given up on `collections.Counter` at this point. The
fact that it's a hybrid mapping/multiset is the cause of all the problems, so
I just made my
Ethan Furman added the comment:
We are not rushing into code, we are getting some code, and tests, written to
help define what we are talking about.
So far the feedback has given some more tests to add, and some things to change
(such as only comparing with other Counters).
The big question
Serhiy Storchaka added the comment:
This implementation obeys more set properties.
--
Added file:
http://bugs.python.org/file36801/issue22515_partial_order_counter_v3.diff
___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue22515
Ram Rachum added the comment:
Attached patch of implementation with tests. I haven't actually run this
(because I don't know how to run Python's test suite) so there are likely to be
bugs. if there's general agreement about this direction I'll figure out how to
run the test so I could ensure
Ram Rachum added the comment:
Fixed patch attached. Still needs someone to run it and see whether there are
any bugs.
--
Added file: http://bugs.python.org/file36792/patch2.patch
___
Python tracker rep...@bugs.python.org
Ethan Furman added the comment:
Testing the patch...
--
___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue22515
___
___
Python-bugs-list mailing list
Ethan Furman added the comment:
In going through the tests I have found an edge-case that I am unsure of how to
handle:
Counter(a=1) Counter(a=1, b=1)
On the one hand, they both have the same value for 'a'; on the other hand, the
second counter has more elements...
So should the result
Antoine Pitrou added the comment:
Counter(a=1) Counter(a=1, b=1)
Do an analogy with sets and the answer will be obvious.
--
___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue22515
___
Changes by Ethan Furman et...@stoneleaf.us:
--
stage: test needed - patch review
___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue22515
___
___
Ethan Furman added the comment:
I am not a mathematician -- feel free to include the answer with your hints. ;)
If my analogy is correct, this situation is similar to
{1} {1, 2}
Which is True. Can someone verify that I am correct?
--
___
Ram Rachum added the comment:
Yes, correct.
--
___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue22515
___
___
Python-bugs-list mailing list
Ethan Furman added the comment:
New patch attached.
--
Added file: http://bugs.python.org/file36794/issue22515.stoneleaf.patch.01
___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue22515
___
Ethan Furman added the comment:
I, myself, wrote:
-
At least, it will until we fix that bug. ;)
Happily, reading the whole documentation revealed that non-integer values are
allowed, so it's not a bug. :)
--
___
Python tracker
Eric V. Smith added the comment:
Is there some particular problem you're trying to solve, which this would make
easier?
Without a use case, I'm -1.
--
nosy: +eric.smith
___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue22515
Ram Rachum added the comment:
I needed it for an internal calculation in a combinatorics package I'm writing.
Do you want me to take the time to explain the calculation? It's quite complex.
--
___
Python tracker rep...@bugs.python.org
Eric V. Smith added the comment:
No need to explain it. It sounds like it's not generally useful, so I'm still
-1.
--
___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue22515
___
Antoine Pitrou added the comment:
Even if you don't find it useful, Eric, it doesn't take up the method space.
You can very easily ignore it, there's no cognitive burden.
--
___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue22515
Ethan Furman added the comment:
Curiousity question: What happens if you try to sort a list of partially
ordered Counters?
--
___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue22515
___
Antoine Pitrou added the comment:
If it is so specialized as to only be needed in complex combinatorial
calculations
How do you know it is only needed in complex combinatorial calculations?
What happens if you try to sort a list of partially ordered Counters?
Try it with partially ordered
Ethan Furman added the comment:
If it is so specialized as to only be needed in complex combinatorial
calculations, does it belong in the general-purpose part of the language?
After all, we have the math and cmath modules for more specialized arithmetic
operations.
--
Ram Rachum added the comment:
I don't see why it's so hard to imagine how this will be used. Say I have a
counter signifying how many of each product I have in my warehouse, and I have
another counter saying how many of each product a client wants. I may use
`counter2 = counter1` to check
Ethan Furman added the comment:
-- s1 = set([1])
-- s2 = set([1, 2])
-- s3 = set([1, 2, 3])
-- s4 = set([2])
-- s5 = set([2, 3])
-- s6 = set([3])
-- l = [s1, s2, s3, s4, s5, s6]
-- sorted(l)
[{1}, {2}, {1, 2}, {3}, {2, 3}, {1, 2, 3}]
-- s1 s4
False
-- s4 s2
True
-- s1 s2
True
-- s4 s6
Steven D'Aprano added the comment:
Ethan said:
If it is so specialized as to only be needed in complex combinatorial
calculations, does it belong in the general-purpose part of the
language?
It's a multi-set, a general purpose and fairly fundamental data type.
Ethan Furman added the comment:
I'll go with +0.5. :)
If this goes in, I think a missing key in either Counter should default to 0
for purposes of the ordering.
--
stage: - test needed
___
Python tracker rep...@bugs.python.org
Ram Rachum added the comment:
If/when there's general agreement that this functionality should be merged in
(assuming the implementation is acceptable), let me know and I'll be happy to
write the code and tests.
--
___
Python tracker
Antoine Pitrou added the comment:
I'll go with +0.5. :)
I was going to make a joke about Counters only accepting integral values, but
the constructor is actually quite laxist:
Counter({'a': 2.5})
Counter({'a': 2.5})
Counter({'a': 2.5 + 1j})
Counter({'a': (2.5+1j)})
Counter({'a': 'b'})
Ethan Furman added the comment:
That does seem odd -- how can you have 'b' of something?
--
___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue22515
___
Ram Rachum added the comment:
The real problem is that `Counter` was put into the standard library with such
lenient conditions on how it should be used-- basically looking at it as a
`dict` subclass rather than a counter, putting emphasis on implementation
rather than purpose, which was a
Stefan Behnel added the comment:
That does seem odd -- how can you have 'b' of something?
Don't ask this kind of question as long as any math guys are listening.
But seriously, I consider this proposal reasonable. If the problem is that the
counter values can be non-integers, then why not
Ram Rachum added the comment:
Stefan: If you'd want to raise an exception, you'll need to define in which
cases. Should it raise an exception for decimal numbers? Complex numbers? etc.
Personally I'd enjoy it raising exceptions in as many situations as possible
(so we could keep Counter usage
Stefan Behnel added the comment:
I'd raise an exception whenever the values of the Counter turn out to be
uncomparable. If users manage to fill Counters with non-number values that are
comparable amongst each other, or even if each key has a value of a different
type, why not just support
Ethan Furman added the comment:
I have to disagree. The intent is clearly expressed in the docs [1]. However,
if I have a need to deal with partial amounts (say, 2.5 apples because I gave
half of one to my horse ;), Counter will still work with that:
-- treats = Counter({'carrots':12,
Ram Rachum added the comment:
Ah, now I understand you Stefan. That sounds like a good scheme; let any
comparison errors between the values simply propagate up.
--
___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue22515
Ethan Furman added the comment:
[1] https://docs.python.org/3/library/collections.html#collections.Counter
--
___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue22515
___
New submission from Ram Rachum:
I suggest implementing `Counter.__lt__` which will be a partial order,
similarly to `set.__lt__`. That is, one counter will be considered
smaller-or-equal to another if for any item in the first counter, the second
counter has an equal or bigger amount of that
Steven D'Aprano added the comment:
On Mon, Sep 29, 2014 at 07:33:21PM +, Ram Rachum wrote:
I suggest implementing `Counter.__lt__` which will be a partial order,
similarly to `set.__lt__`.
Since Counter is described as a multiset, this sounds reasonable to me.
--
nosy:
Serhiy Storchaka added the comment:
What should be result of following operations?
Counter({'a': 0}) Counter({})
Counter({}) Counter({'a': 0})
Counter({'a': -1}) Counter({})
Counter({}) Counter({'a': -1})
--
nosy: +serhiy.storchaka
___
Python
Ram Rachum added the comment:
I suggest they be ignored like in `elements`.
--
___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue22515
___
___
Ram Rachum added the comment:
(I mean, the non-positive values should be ignored.)
--
___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue22515
___
___
Serhiy Storchaka added the comment:
There is other definition of the = operator for sets: A = B is equivalent
to len(A - B) == 0. Extending to Counter this can mean
len(A.subtract(B).elements()) == 0.
--
___
Python tracker rep...@bugs.python.org
Ethan Furman added the comment:
What would be the result of
Counter({'a':1, 'b':2}) Counter({'a':2, 'b':1})
?
--
nosy: +ethan.furman
___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue22515
Ram Rachum added the comment:
False, like with sets.
--
___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue22515
___
___
Python-bugs-list mailing list
R. David Murray added the comment:
Thanks, Ethan. I had a feeling that this wasn't well defined but I couldn't
come up with an example :)
--
nosy: +r.david.murray
___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue22515
Ram Rachum added the comment:
David, there's nothing here that isn't well defined. It's simply a partial
order, not a total order. We have the same for sets.
--
___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue22515
Ethan Furman added the comment:
set's don't have values, and you are wanting to implement the partial ordering
based on the values. (side-note: how does partial-ordering work for sets?)
That is, one counter will be considered smaller-or-equal to another if for any
item in the first counter,
Changes by Josh Rosenberg shadowranger+pyt...@gmail.com:
--
nosy: +josh.rosenberg
___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue22515
___
___
Ram Rachum added the comment:
Ethan, I don't understand what the problem is. I also don't understand your
side note question how does partial-ordering work for sets? I'm not sure what
you're asking.
That is, one counter will be considered smaller-or-equal to another if for
any
item in
Ram Rachum added the comment:
To put it another way: In Python sets, `a = b` iff `b` has everything that `a`
has, and possibly more. I'm proposing the exact same definition for counters.
True, the implementation might be different because sets are not dicts and
don't have `.values()`, but
Ethan Furman added the comment:
That is certainly a better definition. If you carefully reread your original
post you will see that you wrote something different ('any' instead of
'every'). Also, your OP uses '__lt__' but talks about 'less-than-or-equal --
somewhat confusing. ;)
Ram Rachum added the comment:
You're right, sorry. I meant the mathematical for any which means for
every: https://en.wikipedia.org/wiki/List_of_mathematical_symbols (See for
any;)
--
___
Python tracker rep...@bugs.python.org
Antoine Pitrou added the comment:
The request sounds ok to me. As in the corner case of negative values, it seems
that Counter currently doesn't elide zero values, e.g.:
Counter({'a': 0}) == Counter({})
False
Therefore, we should have:
Counter({'a': -1}) Counter({'a': 0})
True
but:
Ram Rachum added the comment:
Shall I write a patch?
--
___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue22515
___
___
Python-bugs-list mailing list
Ethan Furman added the comment:
I think the final call is Raymond's (whether to accept the patch), but go
ahead. Worst case scenario is you'll have your own thoroughly tested
PartiallyOrderedCounter you can use in your own code. :)
--
nosy: +rhettinger
type: - enhancement
Ram Rachum added the comment:
If that's the case I'd prefer Raymond to first say whether this feature is
generally welcome before spending my time on making a patch.
--
___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue22515
70 matches
Mail list logo