[Tutor] Calculating and returning possible combinations of elements from a given set

Dave Angel davea at ieee.org
Wed Jul 28 15:22:45 CEST 2010


ZUXOXUS wrote:
> 2010/7/28 Dave Angel <davea at ieee.org>
> <snip>
>> Your latest version gets the product of two.  But if you want an arbitrary
>> number, instead of repeating the iterable ('ABC' in your case), you can use
>> a repeat count.  That's presumably what you were trying to do in your
>> earlier incantation.  But you forgot the 'repeat' keyword:
>>
>> for prod in itertools.product('ABC', repeat=4):
>>   xxxx
>>
>> will give you all the four-tuples.
>>
>> DaveA
>>
>>
>>     
>
> <snip>
> Thanks for the reminder, Dave Angel, and for the 'repeat' keyword!
>
>   
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.

itertools.product(/*iterables/[, /repeat/])

    Cartesian product of input iterables.

    Equivalent to nested for-loops in a generator expression. For
    example, product(A, B) returns the same as ((x,y) for x in A for y
    in B).

    The nested loops cycle like an odometer with the rightmost element
    advancing on every iteration. This pattern creates a lexicographic
    ordering so that if the input’s iterables are sorted, the product
    tuples are emitted in sorted order.

    To compute the product of an iterable with itself, specify the
    number of repetitions with the optional /repeat/ keyword argument.
    For example, product(A, repeat=4) means the same as product(A, A, A, A).

....

Now that example at the end is exactly what you need here. But let's 
look at the first line.

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,
...product("ABC", 2)

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
def product(*iterables, repeat):
.....

then you can call it with
count = 4
product(list1, list2, repeat=count)

and by specifying the 'repeat' keyword, the system knows to stop copying 
your arguments into the iterables collection.

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.

DaveA






More information about the Tutor mailing list