Elizabeth Susan Joseph
Elizabeth Susan Joseph

Reputation: 6515

How to get different combinations in python?

Given Lista each containing an id name (e.g. a), the symbol '=' and a comma separated list of values. I need to generate another list which is a combination of 'id= value' substrings, such that each id-value combination exists in the input and each value is used exactly once.

Lista:
    [
    'a= aVal1,aVal2',
    'b=bVal1,bVal2,bVal3',
    'c= cVal1,cVal2',
    ]

Expected output:

Listb:
    [
    'a=aVal1& b=bVal1&c=cVal1',
    'a=aVal1&b=tyVal1&c=cVal2',
    'a=aVal1&b=tyVal2&c=tzVal1',
    'a=aVal1&b=tyVal2&c=tzVal2',
    ]

I tried to solve this question using itertools.permutations() function, but I was unable to proceed further. What type of approach should I take to solve this problem?

Upvotes: 2

Views: 99

Answers (3)

PM 2Ring
PM 2Ring

Reputation: 55469

I don't normally post complete working solutions to what look like homework problems, so consider yourself lucky. :)

#!/usr/bin/env python

from itertools import product

lista = [
    'a=aVal1,aVal2',
    'b=bVal1,bVal2,bVal3',
    'c=cVal1,cVal2',
]

newlists = []
for s in lista:
    head, _, tail = s.partition('=')
    newlists.append(['%s=%s' % (head, u) for u in tail.split(',')])

listb = ['&'.join(t) for t in product(*newlists)]

for row in listb:
    print row

output

a=aVal1&b=bVal1&c=cVal1
a=aVal1&b=bVal1&c=cVal2
a=aVal1&b=bVal2&c=cVal1
a=aVal1&b=bVal2&c=cVal2
a=aVal1&b=bVal3&c=cVal1
a=aVal1&b=bVal3&c=cVal2
a=aVal2&b=bVal1&c=cVal1
a=aVal2&b=bVal1&c=cVal2
a=aVal2&b=bVal2&c=cVal1
a=aVal2&b=bVal2&c=cVal2
a=aVal2&b=bVal3&c=cVal1
a=aVal2&b=bVal3&c=cVal2

I've changed the name of your lists to lower case - Names beginning with an upper case letter like Lista and Listb are normally reserved for use as class names in Python.

If you don't understand any of the things I've done in this program, please ask and I'll try to explain.


You could do this in one line, but it's not very easy to read:

listb = ['&'.join(t)for t in product(*[['%s=%s'%(i,v)for v in j.split(',')]for i,j in[s.split('=')for s in lista]])]

:)


The string .partition() method splits a string into 3 parts: the substring before the separator, the separator itself, and the substring after the separator.
So head, _, tail = s.partition('=') captures the id into head and all the associated values into tail.
I use _ to capture the separator to indicate that we don't really need that value (since we already know that it's =).
The list comprehension on the next line splits the values up by using .split(',').

Upvotes: 4

Kasravnd
Kasravnd

Reputation: 107287

>>> l=[i.split('=') for i in a]
>>> g=[[i]+j.split(',') for i,j in l]
>>> ['&'.join(('='.join(m),'='.join(k),'='.join(t))) for m,k,t in (product(*[list(combinations(i,2)) for i in g],repeat=1))]
['a= aVal1&b=bVal1&c= cVal1', 'a= aVal1&b=bVal1&c=cVal2', 'a= aVal1&b=bVal1& cVal1=cVal2', 'a= aVal1&b=bVal2&c= cVal1', 'a= aVal1&b=bVal2&c=cVal2', 'a= aVal1&b=bVal2& cVal1=cVal2', 'a= aVal1&b=bVal3&c= cVal1', 'a= aVal1&b=bVal3&c=cVal2', 'a= aVal1&b=bVal3& cVal1=cVal2', 'a= aVal1&bVal1=bVal2&c= cVal1', 'a= aVal1&bVal1=bVal2&c=cVal2', 'a= aVal1&bVal1=bVal2& cVal1=cVal2', 'a= aVal1&bVal1=bVal3&c= cVal1', 'a= aVal1&bVal1=bVal3&c=cVal2', 'a= aVal1&bVal1=bVal3& cVal1=cVal2', 'a= aVal1&bVal2=bVal3&c= cVal1', 'a= aVal1&bVal2=bVal3&c=cVal2', 'a= aVal1&bVal2=bVal3& cVal1=cVal2', 'a=aVal2&b=bVal1&c= cVal1', 'a=aVal2&b=bVal1&c=cVal2', 'a=aVal2&b=bVal1& cVal1=cVal2', 'a=aVal2&b=bVal2&c= cVal1', 'a=aVal2&b=bVal2&c=cVal2', 'a=aVal2&b=bVal2& cVal1=cVal2', 'a=aVal2&b=bVal3&c= cVal1', 'a=aVal2&b=bVal3&c=cVal2', 'a=aVal2&b=bVal3& cVal1=cVal2', 'a=aVal2&bVal1=bVal2&c= cVal1', 'a=aVal2&bVal1=bVal2&c=cVal2', 'a=aVal2&bVal1=bVal2& cVal1=cVal2', 'a=aVal2&bVal1=bVal3&c= cVal1', 'a=aVal2&bVal1=bVal3&c=cVal2', 'a=aVal2&bVal1=bVal3& cVal1=cVal2', 'a=aVal2&bVal2=bVal3&c= cVal1', 'a=aVal2&bVal2=bVal3&c=cVal2', 'a=aVal2&bVal2=bVal3& cVal1=cVal2', ' aVal1=aVal2&b=bVal1&c= cVal1', ' aVal1=aVal2&b=bVal1&c=cVal2', ' aVal1=aVal2&b=bVal1& cVal1=cVal2', ' aVal1=aVal2&b=bVal2&c= cVal1', ' aVal1=aVal2&b=bVal2&c=cVal2', ' aVal1=aVal2&b=bVal2& cVal1=cVal2', ' aVal1=aVal2&b=bVal3&c= cVal1', ' aVal1=aVal2&b=bVal3&c=cVal2', ' aVal1=aVal2&b=bVal3& cVal1=cVal2', ' aVal1=aVal2&bVal1=bVal2&c= cVal1', ' aVal1=aVal2&bVal1=bVal2&c=cVal2', ' aVal1=aVal2&bVal1=bVal2& cVal1=cVal2', ' aVal1=aVal2&bVal1=bVal3&c= cVal1', ' aVal1=aVal2&bVal1=bVal3&c=cVal2', ' aVal1=aVal2&bVal1=bVal3& cVal1=cVal2', ' aVal1=aVal2&bVal2=bVal3&c= cVal1', ' aVal1=aVal2&bVal2=bVal3&c=cVal2', ' aVal1=aVal2&bVal2=bVal3& cVal1=cVal2']

explanation :

First you need to split your string list with = then create g as following :

>>> g
[['a', ' aVal1', 'aVal2'], ['b', 'bVal1', 'bVal2', 'bVal3'], ['c', ' cVal1', 'cVal2']]

now you need to create the combinations of the element of list g with len 2 and after that you need a production of that result!Note that we need to pickup one tuple from each list of below result :

>>> [list(combinations(i,2)) for i in g]
[[('a', ' aVal1'), ('a', 'aVal2'), (' aVal1', 'aVal2')], [('b', 'bVal1'), ('b', 'bVal2'), ('b', 'bVal3'), ('bVal1', 'bVal2'), ('bVal1', 'bVal3'), ('bVal2', 'bVal3')], [('c', ' cVal1'), ('c', 'cVal2'), (' cVal1', 'cVal2')]]

Upvotes: 1

simpletron
simpletron

Reputation: 739

You should have take a look on itertools.product, that may be what you are looking for.

You may easily convert listA to 3 lists:

a = ['aVal1', 'aVal2']
b = ['bVal1', 'bVal2', 'bVal3']
c = ['cVal1', 'cVal2']

then you may try

for x in itertools.product(a, b, c):
   print x

x will be what you want, all the remain work are string concatenating, or string formating.

Update

For more detail, you can use this

all_the_list = []
listB = []
for i in listA:
    name, values = i.split('=');
    k = values.strip().split(',');
    all_the_list.append(k)

// then product the out put
for aV, bV, cV in itertools.product(*all_the_list):
    listB.append('a=%s&b=%s&c=%s'%(aV, bV, cV))

Hope this help

Upvotes: 0

Related Questions