Reputation: 6515
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
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
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
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