<span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; border-collapse: collapse; "><blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; ">
<div class="im" style="color: rgb(80, 0, 80); ">2010/7/28 Dave Angel <<a href="mailto:davea@ieee.org" target="_blank" style="color: rgb(42, 93, 176); ">davea@ieee.org</a>><br></div><snip><div class="im" style="color: rgb(80, 0, 80); ">
<br><blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; ">
Your latest version gets the product of two. But if you want an arbitrary<br>number, instead of repeating the iterable ('ABC' in your case), you can use<br>a repeat count. That's presumably what you were trying to do in your<br>
earlier incantation. But you forgot the 'repeat' keyword:<br><br>for prod in itertools.product('ABC', repeat=4):<br> xxxx<br><br>will give you all the four-tuples.<br><br>DaveA<br><br><br> <br></blockquote>
<br></div><snip><div class="im" style="color: rgb(80, 0, 80); "><br>Thanks for the reminder, Dave Angel, and for the 'repeat' keyword!<br><br> <br></div></blockquote>Since you're new to Python, it's probably useful to expound a little bit, on how you could have figured it out from the help documentation.<br>
<br>itertools.product(/*iterables/[, /repeat/])<br><br> Cartesian product of input iterables.<br><br> Equivalent to nested for-loops in a generator expression. For<br> example, product(A, B) returns the same as ((x,y) for x in A for y<br>
in B).<br><br> The nested loops cycle like an odometer with the rightmost element<br> advancing on every iteration. This pattern creates a lexicographic<br> ordering so that if the input’s iterables are sorted, the product<br>
tuples are emitted in sorted order.<br><br> To compute the product of an iterable with itself, specify the<br> number of repetitions with the optional /repeat/ keyword argument.<br> For example, product(A, repeat=4) means the same as product(A, A, A, A).<br>
<br>....<br><br>Now that example at the end is exactly what you need here. But let's look at the first line.<br><br>See the *iterables in the formal parameter list. The leading * means you can put 1, 2, or as many iterables as you like, and they'll each be treated as an independent dimension in the cartesian product. So when you put the arguments,<br>
...product("ABC", 2)<br><br>the 2 is treated as an iterable, which it isn't. Thus your error. When there are an arbitrary number of such arguments, followed by another optional parameter, there's no way the compiler could guess in which sense you wanted the 2 to be used. So you have to use that parameter's name as a keyword in your call. If you have a function declared as<br>
def product(*iterables, repeat):<br>.....<br><br>then you can call it with<br>count = 4<br>product(list1, list2, repeat=count)<br><br>and by specifying the 'repeat' keyword, the system knows to stop copying your arguments into the iterables collection.<br>
<br>Actually, I suspect that if you specify a repeat count, you can only supply one iterable, but I'm really talking about the language here.<br><br>DaveA</span><br><br><div>****</div><div><br></div><div>Wow, Thank you DaveA, that was very useful.</div>
<div><br></div><div>However, as it usually happens, answers trigger new questions.</div><div><br></div><div>My doubt now is whether I can change the way python show the combinations.</div><div><br></div><div>I mean, here's what python actually does:</div>
<div><br></div><div><div>>>> for prod in itertools.product('abc', repeat=3):</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>print(prod)</div><div><br></div><div>('a', 'a', 'a')</div>
<div>('a', 'a', 'b')</div><div>('a', 'a', 'c')</div><div>('a', 'b', 'a')</div><div>('a', 'b', 'b')</div><div>('a', 'b', 'c')</div>
<div>[...] etc.</div></div><div><br></div><div><br></div><div>what if I want the combinations listed in a... well, in a list, kind of like this:</div><div><br></div><div>('aaa', 'aab', aac', 'aba', 'abb', 'abc' [...]etc.)</div>
<div><br></div><div>can I do that?</div><div><br></div><div>I have checked how the function works (see below), perhaps I have to just change couple of lines of the code and voilá, the result displayed as I want... But unfortunately I'm too newbie for this, or this is too hardcore:</div>
<div><br></div><div><span class="Apple-style-span" style="font-family: sans-serif; font-size: 16px; line-height: 20px; "><pre style="overflow-x: auto; overflow-y: auto; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; background-color: rgb(238, 255, 204); color: rgb(51, 51, 51); line-height: 15px; border-top-width: 1px; border-right-width: initial; border-bottom-width: 1px; border-left-width: initial; border-top-style: solid; border-right-style: none; border-bottom-style: solid; border-left-style: none; border-top-color: rgb(170, 204, 153); border-right-color: initial; border-bottom-color: rgb(170, 204, 153); border-left-color: initial; ">
<span class="k" style="color: rgb(0, 112, 32); font-weight: bold; ">def</span> <span class="nf" style="color: rgb(6, 40, 126); ">product</span><span class="p">(</span><span class="o" style="color: rgb(102, 102, 102); ">*</span><span class="n">args</span><span class="p">,</span> <span class="o" style="color: rgb(102, 102, 102); ">**</span><span class="n">kwds</span><span class="p">):</span>
<span class="c" style="color: rgb(64, 128, 144); font-style: italic; "># product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy</span>
<span class="c" style="color: rgb(64, 128, 144); font-style: italic; "># product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111</span>
<span class="n">pools</span> <span class="o" style="color: rgb(102, 102, 102); ">=</span> <span class="nb" style="color: rgb(0, 112, 32); ">map</span><span class="p">(</span><span class="nb" style="color: rgb(0, 112, 32); ">tuple</span><span class="p">,</span> <span class="n">args</span><span class="p">)</span> <span class="o" style="color: rgb(102, 102, 102); ">*</span> <span class="n">kwds</span><span class="o" style="color: rgb(102, 102, 102); ">.</span><span class="n">get</span><span class="p">(</span><span class="s" style="color: rgb(64, 112, 160); ">'repeat'</span><span class="p">,</span> <span class="mi" style="color: rgb(32, 128, 80); ">1</span><span class="p">)</span>
<span class="n">result</span> <span class="o" style="color: rgb(102, 102, 102); ">=</span> <span class="p">[[]]</span>
<span class="k" style="color: rgb(0, 112, 32); font-weight: bold; ">for</span> <span class="n">pool</span> <span class="ow" style="color: rgb(0, 112, 32); font-weight: bold; ">in</span> <span class="n">pools</span><span class="p">:</span>
<span class="n">result</span> <span class="o" style="color: rgb(102, 102, 102); ">=</span> <span class="p">[</span><span class="n">x</span><span class="o" style="color: rgb(102, 102, 102); ">+</span><span class="p">[</span><span class="n">y</span><span class="p">]</span> <span class="k" style="color: rgb(0, 112, 32); font-weight: bold; ">for</span> <span class="n">x</span> <span class="ow" style="color: rgb(0, 112, 32); font-weight: bold; ">in</span> <span class="n">result</span> <span class="k" style="color: rgb(0, 112, 32); font-weight: bold; ">for</span> <span class="n">y</span> <span class="ow" style="color: rgb(0, 112, 32); font-weight: bold; ">in</span> <span class="n">pool</span><span class="p">]</span>
<span class="k" style="color: rgb(0, 112, 32); font-weight: bold; ">for</span> <span class="n">prod</span> <span class="ow" style="color: rgb(0, 112, 32); font-weight: bold; ">in</span> <span class="n">result</span><span class="p">:</span>
<span class="k" style="color: rgb(0, 112, 32); font-weight: bold; ">yield</span> <span class="nb" style="color: rgb(0, 112, 32); ">tuple</span><span class="p">(</span><span class="n">prod</span><span class="p">)</span></pre>
</span></div><div><br></div><div>Any ideas will be very much appreciated.</div><div><br></div><div><div class="gmail_quote">2010/7/28 Dave Angel <span dir="ltr"><<a href="mailto:davea@ieee.org">davea@ieee.org</a>></span><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">ZUXOXUS wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">
2010/7/28 Dave Angel <<a href="mailto:davea@ieee.org" target="_blank">davea@ieee.org</a>><br></div>
<snip><div class="im"><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Your latest version gets the product of two. But if you want an arbitrary<br>
number, instead of repeating the iterable ('ABC' in your case), you can use<br>
a repeat count. That's presumably what you were trying to do in your<br>
earlier incantation. But you forgot the 'repeat' keyword:<br>
<br>
for prod in itertools.product('ABC', repeat=4):<br>
xxxx<br>
<br>
will give you all the four-tuples.<br>
<br>
DaveA<br>
<br>
<br>
<br>
</blockquote>
<br></div>
<snip><div class="im"><br>
Thanks for the reminder, Dave Angel, and for the 'repeat' keyword!<br>
<br>
<br>
</div></blockquote>
Since you're new to Python, it's probably useful to expound a little bit, on how you could have figured it out from the help documentation.<br>
<br>
itertools.product(/*iterables/[, /repeat/])<br>
<br>
Cartesian product of input iterables.<br>
<br>
Equivalent to nested for-loops in a generator expression. For<br>
example, product(A, B) returns the same as ((x,y) for x in A for y<br>
in B).<br>
<br>
The nested loops cycle like an odometer with the rightmost element<br>
advancing on every iteration. This pattern creates a lexicographic<br>
ordering so that if the input’s iterables are sorted, the product<br>
tuples are emitted in sorted order.<br>
<br>
To compute the product of an iterable with itself, specify the<br>
number of repetitions with the optional /repeat/ keyword argument.<br>
For example, product(A, repeat=4) means the same as product(A, A, A, A).<br>
<br>
....<br>
<br>
Now that example at the end is exactly what you need here. But let's look at the first line.<br>
<br>
See the *iterables in the formal parameter list. The leading * means you can put 1, 2, or as many iterables as you like, and they'll each be treated as an independent dimension in the cartesian product. So when you put the arguments,<br>
...product("ABC", 2)<br>
<br>
the 2 is treated as an iterable, which it isn't. Thus your error. When there are an arbitrary number of such arguments, followed by another optional parameter, there's no way the compiler could guess in which sense you wanted the 2 to be used. So you have to use that parameter's name as a keyword in your call. If you have a function declared as<br>
def product(*iterables, repeat):<br>
.....<br>
<br>
then you can call it with<br>
count = 4<br>
product(list1, list2, repeat=count)<br>
<br>
and by specifying the 'repeat' keyword, the system knows to stop copying your arguments into the iterables collection.<br>
<br>
Actually, I suspect that if you specify a repeat count, you can only supply one iterable, but I'm really talking about the language here.<br>
<br>
DaveA<br>
<br>
<br>
<br>
<br>
</blockquote></div><br></div>