Python some special products of this list

I would like to find a way for the possible products of this list. Below is an example

So far I have tried this:

for p in itertools.product(the_list, repeat=2): print p 

But this returns all the features that can be created from this list. Could you help me create the following example?

Example:

 the_list=['A1','A2','A3','B1','B2','B3','C1','C2','C3','D1','D2','D3'] The results should be: ['A1A2','A1B2','A1C2','A1D2','A2A3','A2B3','A2C3','A2D3','A3A1','A3B1','A3C1','A3D1' 'B1A2,'B2A3'... 'C1A2'...'] 

Basically, in capital letters indicates the state, and numbers - the sequence. So, if it starts with A1, it can only continue with state number 2, for example, first A1, then A2 or B2 or C2 or D2. It is also circular, which means that A3 is followed by either A1, B1, C1, or D1.

+4
source share
4 answers
 l=['A1','A2','A3','B1','B2','B3','C1','C2','C3','D1','D2','D3'] result = [i + j for i in l for j in l if int(j[1]) == int(i[1]) + 1 or (j[1] == '1' and i[1] == '3')] print(result) 

It is output:

 ['A1A2', 'A1B2', 'A1C2', 'A1D2', 'A2A3', 'A2B3', 'A2C3', 'A2D3', 'A3A1', 'A3B1', 'A3C1', 'A3D1', 'B1A2', 'B1B2', 'B1C2', 'B1D2', 'B2A3', 'B2B3', 'B2C3', 'B2D3', 'B3A1', 'B3B1', 'B3C1', 'B3D1', 'C1A2', 'C1B2', 'C1C2', 'C1D2', 'C2A3', 'C2B3', 'C2C3', 'C2D3', 'C3A1', 'C3B1', 'C3C1', 'C3D1', 'D1A2', 'D1B2', 'D1C2', 'D1D2', 'D2A3', 'D2B3', 'D2C3', 'D2D3', 'D3A1', 'D3B1', 'D3C1', 'D3D1'] 

If you prefer readability over compactness, expand single-line

 l=['A1','A2','A3','B1','B2','B3','C1','C2','C3','D1','D2','D3'] result = [] for i in l: for j in l: if int(j[1]) == int(i[1]) + 1 or (j[1] == '1' and i[1] == '3'): result.append(i+j) print(result) 

It outputs the same thing.

+2
source

According to your current list, there are not many values ​​that need to be removed if you just want to get all the permutations and filter out the unwantedness after the fact. Do it lazily, and those that you filter will be much less common than those that you store. (I will use list comprehension for transparency β€” turn it into a generator expression in your actual code.)

 >>> from itertools import permutations >>> [''.join(x) for x in permutations(l, 2) if int(x[0][1]) % 3 == int(x[1][1]) - 1] ['A1A2', 'A1B2', 'A1C2', 'A1D2', 'A2A3', 'A2B3', 'A2C3', 'A2D3', 'A3A1', 'A3B1', 'A3C1', 'A3D1', 'B1A2', 'B1B2', 'B1C2', 'B1D2', 'B2A3', 'B2B3', 'B2C3', 'B2D3', 'B3A1', 'B3B1', 'B3C1', 'B3D1', 'C1A2', 'C1B2', 'C1C2', 'C1D2', 'C2A3', 'C2B3', 'C2C3', 'C2D3', 'C3A1', 'C3B1', 'C3C1', 'C3D1', 'D1A2', 'D1B2', 'D1C2', 'D1D2', 'D2A3', 'D2B3', 'D2C3', 'D2D3', 'D3A1', 'D3B1', 'D3C1', 'D3D1'] 

Update to respond to John's comment: Assuming each state has the same sequence size:

 >>> seq_size = len([x for x in l if x[0] == 'A']) # Get the length of the sequence of A >>> [''.join(x) for x in permutations(l, 2) if int(x[0][1:]) % seq_size == int(x[1][1:]) - 1] 

Update to summarize the following series of comments for John:

 #!env python '''Get all the permutations of pieces up to a certain size where the sequence numbers of each piece occur in order, cyclically. So for a permutation_size of 5, 1->2, 2->3, 3->4, 4->5, 5->1.''' from string import uppercase from itertools import permutations num_states = 5 seq_size = 13 group_size = 3 the_list = [char + str(1 + num) for char in uppercase[:num_states] for num in xrange(seq_size)] def groupFilter(pieces): '''True for a list whose sequence is in order. False otherwise.''' ints = [int(piece.lstrip(uppercase)) for piece in pieces] offset = ints[0] % seq_size for i, piece in enumerate(ints): if offset + i != piece % seq_size: return False return True [''.join(group) for group in permutations(the_list, group_size) if groupFilter(group)] 
+1
source

You can break it down into a sequence by having

 first = ['A1', 'B1', 'C1', 'D1'] second = ['A2', 'B2', 'C2', 'D2'] ... 

Then, taking the product of two consecutive lists, you should give what you want (if I understood your question correctly ...).

0
source

Just in case, you need something that can work with itertools.product , you can try this (with pleasure we will choose if it does not match your "real" input - this is an interesting problem :)). This can be wrapped in fewer lines, but it loses a lot of readability, so hopefully this will be somewhat useful:

 from itertools import groupby, product from operator import itemgetter the_list = ['A1','A2','A3','B1','B2','B3','C1','C2','C3','D1','D2','D3'] # In order to work properly with groupby, we sort the list by the # number at the end of the string s = sorted(the_list, key=itemgetter(-1)) # Now we create a list of lists, each sub-list containing values # with the same ending number (ie ['A1', 'B1', 'C1', 'D1']) j = [list(g) for _, g in groupby(s, key=itemgetter(-1))] # Now we create our final list results = [] # Here we iterate through our grouped lists, using product # similar to how you did before to create the combined strings for index, r in enumerate(j): # This is the piece that lets us 'loop' the list - # on the first iteration, the value is -(3)+1+0 = -2, # which we use as our list index. This will return the item # 'ahead' of the current one in our main list, and when it # reaches the last (index=2) item, the value is -(3)+1+2 = 0 (beginning) inc = -len(j) + 1 + index # Now we just iterate through the items in our sub-list, pairing with # the items in the 'next' sub-list for val in r: results += [k+v for k, v in product([val], j[inc])] print results 

Output:

 ['A1A2', 'A1B2', 'A1C2', 'A1D2', 'B1A2', 'B1B2', 'B1C2', 'B1D2', 'C1A2', 'C1B2', 'C1C2', 'C1D2', 'D1A2', 'D1B2', 'D1C2', 'D1D2', ' A2A3', 'A2B3', 'A2C3', 'A2D3', 'B2A3', 'B2B3', 'B2C3', 'B2D3', 'C2A3', 'C2B3', 'C2C3', 'C2D3', 'D2A3', 'D2B3', 'D2C3', 'D2D3', 'A3A1', 'A3B1', 'A3C1', 'A3D1', 'B3A1', 'B3B1', 'B3C1', 'B3D1', 'C3A1', 'C3B1', 'C3C1', 'C3D1', 'D3A1', 'D3B1', 'D3C1', 'D3D1'] 
0
source

All Articles