Additional behaviour for itertools.combinations
I'm not sure if it's the right place to post it. If so - I'll be glad to learn where is one. Anyway: I think the function itertools.combinations would benefit from making the 'r' (length of the combinations) argument optionally a sequence. With that change one could call combinations(sequence, [2, 3]) in order to get all combinations of length 2 and 3. In particular, one could call combinations(sequence, range(len(sequence)) in order to get *all* combinations of given sequence. The change would be backwards compatible as it would check for sequential arguments. Is it worth the shot? best regards Konrad PS. Didn't want to spoil the beginning of the post, but I consider it to be a good practice to introduce oneself when posting the first time, so: Hello, my name is Konrad, I'm an IT student and I'm following python-dev for some time, but never posted before.
From: "Konrad Delong" <konryd@gmail.com>
I'm not sure if it's the right place to post it. If so - I'll be glad to learn where is one.
Please post a feature request on the bug tracker and assign it to me.
Anyway: I think the function itertools.combinations would benefit from making the 'r' (length of the combinations) argument optionally a sequence.
With that change one could call combinations(sequence, [2, 3]) in order to get all combinations of length 2 and 3. In particular, one could call combinations(sequence, range(len(sequence)) in order to get *all* combinations of given sequence.
This design is similar to the API for similar functionality in mathematica. The question is whether there are sufficient worthwhile use cases to warrant the added API complexity and algorithm complexity. The latter is a bit tricky if we want to maintain the lexicographic ordering and the notion of combinations being a subsequence of the permutations code. Since I expect students to be among the users for the comb/perm functions, there is some merit to keeping the API as simple as possible. Besides, it is not hard to use the existing tool as a primitive to get to the one you want: def mycombinations(iterable, r_seq): # mycombinations('abc', [1,2]) --> A B C AB AC BC iterable = list(iterable) return chain.from_iterable(imap(combinations, repeat(iterable), r_seq))
PS. Didn't want to spoil the beginning of the post, but I consider it to be a good practice to introduce oneself when posting the first time, so: Hello, my name is Konrad, I'm an IT student and I'm following python-dev for some time, but never posted before.
Hello Konrad. Welcome to python-dev. Raymond Hettinger
Raymond Hettinger wrote:
Since I expect students to be among the users for the comb/perm functions, there is some merit to keeping the API as simple as possible. Besides, it is not hard to use the existing tool as a primitive to get to the one you want:
def mycombinations(iterable, r_seq): # mycombinations('abc', [1,2]) --> A B C AB AC BC iterable = list(iterable) return chain.from_iterable(imap(combinations, repeat(iterable), r_seq))
Perhaps a reasonable starting point would be to include this as one of the example itertools recipes in the documentation? Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia ---------------------------------------------------------------
Raymond Hettinger wrote:
Since I expect students to be among the users for the comb/perm functions, there is some merit to keeping the API as simple as possible. Besides, it is not hard to use the existing tool as a primitive to get to the one you want:
def mycombinations(iterable, r_seq): # mycombinations('abc', [1,2]) --> A B C AB AC BC iterable = list(iterable) return chain.from_iterable(imap(combinations, repeat(iterable), r_seq))
[Nick Coglan]
Perhaps a reasonable starting point would be to include this as one of the example itertools recipes in the documentation?
I would have suggested that but recipe itself is use case challenged. The OP did not mention any compelling use cases or motivations. Essentially, he just pointed-out that it is possible, not that it is desirable. I can't the of a case where I've wanted to loop over variable length subsequences. Having for-loops with tuple unpacking won't work because the combos have more than one possible size. This seems like a hypergeneralization to me. Raymond
On Sun, 25 Jan 2009 02:33:37 pm Raymond Hettinger wrote:
Raymond Hettinger wrote:
Since I expect students to be among the users for the comb/perm functions, there is some merit to keeping the API as simple as possible. Besides, it is not hard to use the existing tool as a primitive to get to the one you want:
def mycombinations(iterable, r_seq): # mycombinations('abc', [1,2]) --> A B C AB AC BC iterable = list(iterable) return chain.from_iterable(imap(combinations, repeat(iterable), r_seq))
[Nick Coglan]
Perhaps a reasonable starting point would be to include this as one of the example itertools recipes in the documentation?
I would have suggested that but recipe itself is use case challenged. The OP did not mention any compelling use cases or motivations. Essentially, he just pointed-out that it is possible, not that it is desirable.
I can't the of a case where I've wanted to loop over variable length subsequences. Having for-loops with tuple unpacking won't work because the combos have more than one possible size.
This seems like a hypergeneralization to me.
Does answering homework questions count as a use-case? http://mathforum.org/library/drmath/view/56121.html Also calculating the odds of winning Powerball: http://mathforum.org/library/drmath/view/56122.html The number of combinations taken (1, 2, 3, ..., n) at a time is closely related to the Bell Numbers. And according to Wikipedia, the oldest known reference to combinatrics included such a question. http://en.wikipedia.org/wiki/History_of_combinatorics Having said all that, I'm inclined to agree that this is an over-generalisation. As far as I can tell, there's no name for this in mathematics, which suggests that useful applications and theorems are both rare. In any case, it's not that difficult to create a generator to yield all the combinations: (comb for k in ks for comb in itertools.combinations(seq, k)) I'm with Nick that this would make a good example for the documentation. I don't object to combinations growing the extra functionality, but if it does, people will ask why permutations doesn't as well. -- Steven D'Aprano
participants (4)
-
Konrad Delong
-
Nick Coghlan
-
Raymond Hettinger
-
Steven D'Aprano