I think this should be separated function.
_______________________________________________
Python-ideas mailing list
Python...@python.org
https://mail.python.org/mailman/listinfo/python-ideas
_______________________________________________
Python-ideas mailing list
Python...@python.org
https://mail.python.org/mailman/listinfo/python-ideas
What would you like this hypothetical function to output here:>>> from itertools import permutations>>> from decimal import Decimal as D>>> from fractions import Fraction as F
>>> items = (3, 3.0, D(3), F(3,1), "aa", "AA".lower(), "a"+"a")>>> list(permutations(items))It's neither QUITE equality nor identity you are looking for, I think, in nonredundant_permutation():>> "aa" == "AA".lower(), "aa" is "AA".lower()(True, False)>>> "aa" == "a"+"a", "aa" is "a"+"a"(True, True)>>> D(3) == 3.0, D(3) is 3.0(True, False)
On Fri, Oct 11, 2013 at 11:38 AM, Neil Girdhar <miste...@gmail.com> wrote:
_______________________________________________
Python-ideas mailing list
Python...@python.org
https://mail.python.org/mailman/listinfo/python-ideas
---
You received this message because you are subscribed to a topic in the Google Groups "python-ideas" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/python-ideas/dDttJfkyu2k/unsubscribe.
To unsubscribe from this group and all its topics, send an email to python-ideas...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
--
--- You received this message because you are subscribed to a topic in the Google Groups "python-ideas" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/python-ideas/dDttJfkyu2k/unsubscribe.
To unsubscribe from this group and all its topics, send an email to python-ideas+unsubscribe@googlegroups.com.
On 12 Oct 2013 08:45, "David Mertz" <me...@gnosis.cx> wrote:
>
>
> I realize after reading http://stackoverflow.com/questions/6284396/permutations-with-unique-values that my version was ALMOST right:
>
> def nonredundant_permutations(seq, r=None):
> last = ()
> for perm in permutations(sorted(seq), r):
> if perm > last:
> yield perm
> last = perm
>
> I can't look only for inequality, but must use the actual comparison.
>
> >>> ["".join(x) for x in nonredundant_permutations('aaabb',3)]
> ['aaa', 'aab', 'aba', 'abb', 'baa', 'bab', 'bba']
> >>> list(nonredundant_permutations([F(3,1), D(3.0), 3.0]))
> [(Fraction(3, 1), Decimal('3'), 3.0)]
>
> Of course, this approach DOES rely on the order in which itertools.permutations() returns values. However, it's a bit more compact than MRAB's version.
As there is no requirement that entries in a sequence handled by itertools.permutations be sortable, so the original question of why this isn't done by default has been answered (the general solution risks consuming too much memory, while the memory efficient solution constrains the domain to only sortable sequences).
Cheers,
Nick.
>>> To unsubscribe from this group and all its topics, send an email to python-ideas...@googlegroups.com.
>>> For more options, visit https://groups.google.com/groups/opt_out.
>>
>>
>>
>> _______________________________________________
>> Python-ideas mailing list
>> Python...@python.org
>> https://mail.python.org/mailman/listinfo/python-ideas
>>
>
>
>
> --
> Keeping medicines from the bloodstreams of the sick; food
> from the bellies of the hungry; books from the hands of the
> uneducated; technology from the underdeveloped; and putting
> advocates of freedom in prisons. Intellectual property is
> to the 21st century what the slave trade was to the 16th.
>
I dispute this entire premise. Take a simple (and stereotypical)
example, picking balls from an urn.
Say that you have three Red and Two black balls, and randomly select
without replacement. If you count only unique permutations, you get only
four possibilities:
py> set(''.join(t) for t in itertools.permutations('RRRBB', 2))
{'BR', 'RB', 'RR', 'BB'}
which implies that drawing RR is no more likely than drawing BB, which
is incorrect. The right way to model this experiment is not to count
distinct permutations, but actual permutations:
py> list(''.join(t) for t in itertools.permutations('RRRBB', 2))
['RR', 'RR', 'RB', 'RB', 'RR', 'RR', 'RB', 'RB', 'RR', 'RR', 'RB', 'RB',
'BR', 'BR', 'BR', 'BB', 'BR', 'BR', 'BR', 'BB']
which makes it clear that there are two ways of drawing BB compared to
six ways of drawing RR. If that's not obvious enough, consider the case
where you have two thousand red balls and two black balls -- do you
really conclude that there are the same number of ways to pick RR as BB?
So I disagree that counting only distinct permutations is the most
useful or common convention. If you're permuting a collection of
non-distinct values, you should expect non-distinct permutations.
I'm trying to think of a realistic, physical situation where you would
only want distinct permutations, and I can't.
> Should we consider fixing itertools.permutations and to output only unique
> permutations (if possible, although I realize that would break code).
Absolutely not. Even if you were right that it should return unique
permutations, and I strongly disagree that you were, the fact that it
would break code is a deal-breaker.
--
Steven
On 12 Oct 2013 12:56, "Neil Girdhar" <miste...@gmail.com> wrote:
>
> I honestly think that Python should stick to the mathematical definition of permutations rather than some kind of consensus of the tiny minority of people here. When next_permutation was added to C++, I believe the whole standards committee discussed it and they came up with the thing that makes the most sense. The fact that dict and set use equality is I think the reason that permutations should use equality.
Why should the behaviour of hash based containers limit the behaviour of itertools?
Python required a permutation solution that is memory efficient and works with arbitrary objects, so that's what itertools provides.
However, you'd also like a memory efficient iterator for *mathematical* permutations that pays attention to object values and filters out equivalent results.
I *believe* the request is equivalent to giving a name to the following genexp:
(k for k, grp in groupby(permutations(sorted(input))))
That's a reasonable enough request (although perhaps more suited to the recipes section in the itertools docs), but conflating it with complaints about the way the existing iterator works is a good way to get people to ignore you (especially now the language specific reasons for the current behaviour have been pointed out, along with confirmation of the fact that backwards compatibility requirements would prohibit changing it even if we wanted to).
Cheers,
Nick.
> I honestly think that Python should stick to the mathematical
> definition of permutations rather than some kind of consensus of
> the tiny minority of people here.
Is there an agreed mathematical definition of permutations of
*sequences*? Every definition I can find refers to permutations of
*sets*. I think any categorist would agree that there are a large
number of maps of _Sequence_ to _Set_, in particular the two obviously
useful ones[1]: the one that takes each element of the sequence to a
*different* element of the corresponding set, and the one that takes
equal elements of the sequence to the *same* element of the
corresponding set. The corresponding set need not be the underlying
set of the sequence, and which one is appropriate presumably depends
on applications.
> When next_permutation was added to C++, I believe the whole
> standards committee discussed it and they came up with the thing
> that makes the most sense.
To the negligible (in several senses of the word) fraction of humanity
that participates in C++ standardization. Python is not C++ (thanking
all the Roman and Greek gods, and refusing to identify Zeus with
Jupiter, nor Aphrodite with Venus<wink/>).
> The fact that dict and set use equality is I think the reason that
> permutations should use equality.
Sequences are not sets, and dict is precisely the wrong example for
you to use, since it makes exactly the point that values that are
identical may be bound to several different keys. We don't unify keys
in a dict just because the values are identical (or equal). Similar,
in representing a sequence as a set, we use a set of ordered pairs,
with the first component an unique integer indicating position, and
the second the sequence element.
Since there are several useful mathematical ways to convert sequences
to sets, and in particular one very similar, if not identical, to the
one you like is enshrined in the very convenient constructor set(), I
think it's useful to leave it as it is.
> It is universally agreed that a list of n distinct symbols has n!
> permutations.
But that's because there's really no sensible definition of
"underlying set" for such a list except the set containing exactly the
same elements as the list.[2] But there is no universal agreement
that "permutations of a list" is a sensible phrase.
For example, although the Wikipedia article Permutation refers to
lists of permutations, linked list representations of data, to the
"list of objects" for use in Cauchy's notation, and to the cycle
representation as a list of sequences, it doesn't once refer to
permutation of a list.
They're obvious not averse to discussing lists, but the word use for
the entity being permuted is invariably "set".
Footnotes:
[1] And some maps not terribly useful for our purposes, such as one
that maps all sequences to a singleton.
[2] A categorist would disagree, but that's not interesting.
On Oct 11, 2013, at 19:48, David Mertz <me...@gnosis.cx> wrote:I agree with the rest of your message, but I still think you're wrong here. Anyone who is surprised by distinct_permutations((3.0, 3)) treating the two values the same would be equally surprised by {3.0, 3} having only one member. Or by groupby((3.0, 'a'), (3, 'b')) only having one group. And so on.
> My feeling, however, is that if one were to trim down the results from a permutations-related function, it is more interesting to me to only eliminate IDENTICAL items, not to eliminate merely EQUAL ones.
In Python, sets, dict keys, groups, etc. work by ==. That was a choice that could have been made differently, but Python made that choice long ago, and has applied it completely consistently, and it would be very strange to choose differently in this case.
Why not just use the standard python way to generalize this: "key" rather than the nonstandard "filter_by".
--
--- You received this message because you are subscribed to a topic in the Google Groups "python-ideas" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/python-ideas/dDttJfkyu2k/unsubscribe.
To unsubscribe from this group and all its topics, send an email to python-ideas+unsubscribe@googlegroups.com.
On 12 Oct 2013 17:18, "Neil Girdhar" <miste...@gmail.com> wrote:
>
> I'm sorry, but I can't find a reference supporting the statement that the current permutations function is consistent with the mathematical definition. Perhaps you would like to find a reference? A quick search yielded the book "the Combinatorics of Permutations": http://books.google.ca/books?id=Op-nF-mBR7YC&lpg=PP1 Please look in the chapter "Permutation of multisets".
Itertools effectively produces the permutation of (index, value) pairs. Hence Steven's point about the permutations of a list not being mathematically defined, so you have to decide what set to map it to in order to decide what counts as a unique value. The mapping itertools uses considers position in the iterable relevant so exchanging two values that are themselves equivalent is still considered a distinct permutation since their original position is taken into account. Like a lot of mathematics, it's a matter of paying close attention to which entities are actually being manipulated and how the equivalence classes are being defined :)
Hence the current proposal amounts to adding another variant that provides the permutations of an unordered multiset instead of those of a set of (index, value) 2-tuples (with the indices stripped from the results).
One interesting point is that combining collections.Counter.elements() with itertools.permutations() currently does the wrong thing, since itertools.permutations() *always* considers iterable order significant, while for collections.Counter.elements() it's explicitly arbitrary.
Cheers,
Nick.
One interesting point is that combining collections.Counter.elements() with itertools.permutations() currently does the wrong thing, since itertools.permutations() *always* considers iterable order significant, while for collections.Counter.elements() it's explicitly arbitrary.
On Oct 11, 2013, at 11:38 AM, Neil Girdhar <miste...@gmail.com> wrote:Should we consider fixing itertools.permutations and to output only unique permutations (if possible, although I realize that would break code). It is completely non-obvious to have permutations returning duplicates.No thanks. The current design was done on purpose. It is simple, fast, flexible and fits neatly with the other combinatoric iterators.The docs are clear about what permutations() does:"Elements are treated as unique based on their position, not on their value. So if the input elements are unique, there will be no repeat values in each permutation."So, if you want to "output only unique permutations", then use set() to make the inputs unique: permutations(set(population), n).It isn't hard.
Raymond
, I find the current behaviour surprising and would like to see a distinct_permutations function.
How do I start to submit a patch?
the proposal is not to eliminate duplicates from
the population, but from the permutations themselves.
_______________________________________________
Python-ideas mailing list
Python...@python.org
https://mail.python.org/mailman/listinfo/python-ideas
I did but since you showed some code that you said you were working on
I thought you'd be interested to know that it could be improved.
Getting back to your proposal, I disagree that permutations should be
> Anyway, let's not get off topic (permutations).
"fixed". The current behaviour is correct. If I was asked to define a
permutation I would have given definition #3 from Steven's list: a
bijection from a set to itself. Formally a permutation of a collection
of non-unique elements is not defined.
They may also be uses for a function like the one that you proposed
but I've never needed it (and I have used permutations a few times)
and no one in this thread (including you) has given a use-case for
this.
Oscar
On 13 October 2013 17:38, Neil Girdhar <miste...@gmail.com> wrote:Nope, we expressly *don't* want the standard library to be "complete",
> My intuition is that we want Python to be "complete". Many other languages
> can find the permutations of a multiset. Python has a permutations
> function. Many people on stackoverflow expected that function to be able to
> find those permutations.
because that would mean growing to the size of PyPI (or larger).
There's always going to be scope for applications to adopt new domain
specific dependencies with more in-depth support than that provided by
the standard library.
Many standard library modules are in fact deliberately designed as
"stepping stone" modules that will meet the needs of code which have
an incidental relationship to that task, but will need to be replaced
with something more sophisticated for code directly related to that
domain. Many times, that means they will ignore as irrelevant
distinctions that are critical in certain contexts, simply because
they don't come up all that often outside those specific domains, and
addressing them involves making the core module more complicated to
use for more typical cases.
In this case, the proposed alternate permutations mechanism only makes
a difference when:
1. The data set contains equivalent values
2. Input order is not considered significant, so exchanging equivalent
values should *not* create a new permutation (i.e. multiset
permutations rather than sequence permutations).
If users aren't likely to encounter situations where that makes a
difference, then providing both in the standard library isn't being
helpful, it's being actively user hostile by asking them to make a
decision they're not yet qualified to make for the sake of the few
experts that specifically need . Hence Raymond's request for data
modelling problems outside the "learning or studying combinatorics"
context to make the case for standard library inclusion.
Interestingly, I just found another language which has the equivalent
of the currrent behaviour of itertools.permutations: Haskell has it as
Data.List.permutations. As far as I can tell, Haskell doesn't offer
support for multiset permutations in the core, you need an additional
package like Math.Combinatorics (see:
http://hackage.haskell.org/package/multiset-comb-0.2.3/docs/Math-Combinatorics-Multiset.html#g:4).
Since iterator based programming in Python is heavily inspired by
Haskell, this suggests that the current behaviour of
itertools.permutations is appropriate and that Raymond is right to be
dubious about including multiset permutations support directly in the
standard library.
Those interested in improving the experience of writing combinatorics
code in Python may wish to look into helping out with the
combinatorics package on PyPI:
http://phillipmfeldman.org/Python/for_developers.html (For example,
politely approach Phillip to see if he is interested in hosting it on
GitHub or BitBucket, providing Sphinx docs on ReadTheDocs, improving
the PyPI metadata, etc - note I have no experience with this package,
it's just the first hit for "python combinatorics")
If you want to go down the path of only caring about hashable values,
> One suggestion: Why not make it so that itertools.permutations checks if its
> argument is an instance of collections.Mapping? If it is, we could
> interpret the items as a mapping from elements to positive integers, which
> is a compact representation of a multiset. Then, it could do the right
> thing for that case.
you may want to argue for a permutations method on collections.Counter
(it's conceivable that approach has the potential to be even faster
than an approach based on accepting and processing an arbitrary
iterable, since it can avoid generating repeated values in the first
place).
A Counter based multiset permutation algorithm was actually posted to
python-list back in 2009, just after collections.Counter was
introduced: https://mail.python.org/pipermail/python-list/2009-January/521685.html
I just created an updated version of that recipe and posted it as
https://bitbucket.org/ncoghlan/misc/src/default/multiset_permutations.py
By complete I meant that just as if you were to add the "error function, erf" to math, you would want to add an equivalent version to cmath.
I'm now convinced that itertools.permutations is fine as it is. I am not totally convinced that multiset_permutations doesn't belong in itertools,
_______________________________________________
Python-ideas mailing list
Python...@python.org
https://mail.python.org/mailman/listinfo/python-ideas
--
---
You received this message because you are subscribed to a topic in the Google Groups "python-ideas" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/python-ideas/dDttJfkyu2k/unsubscribe.
To unsubscribe from this group and all its topics, send an email to python-ideas...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.