2013-01-05 77 views
4

我想找到給定列表的可能產品的一種方式。下面,我有一個例子Python給定列表的一些特殊產品

到目前爲止,我嘗試這樣做:

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

但是,這種返回可以從給定的列表中產生的所有可能性。你能幫我生成下面的例子嗎?

一個例子:

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'...'] 

基本上,大寫字母指代的狀態和數字是指該序列。所以,如果它以A1開始,它只能繼續保持數字2的狀態,例如,首先是A1,然後是A2或B2或C2或D2。它也是圓形的,意味着A3跟隨A1,B1,C1或D1。

+0

這是你可能就要有用循環手動寫入。用英文分解(就像你已經開始),然後從那裏開始。祝你好運。 –

+0

是的,它是有效的... –

+1

我很困惑......你說它不能以'B2'開始,但'B2A3'是有效的...... – Volatility

回答

2
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) 

此輸出:

['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'] 

如果您更喜歡緊湊的可讀性,那麼向上突破的一個班輪

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) 

它輸出同樣的事情。

0

你可以打破它由序列,具有

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

然後,連續服用兩個表中的產品應該給你你想要的東西(如果我正確地理解你的問題...)。

1

根據您當前的列表,如果您希望在事實之後獲得所有排列並過濾不受歡迎的內容,則不會有太多的值可以消除。懶洋洋地這樣做,你過濾的那些將比你保留的那些更不常見。 (我將使用透明度列表理解 - 把它變成你的實際代碼生成器表達式。)

>>> 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'] 

更新回答約翰的評論: 假設每個國家都有相同的序列大小:

>>> 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] 

更新概括爲約翰的下一個系列的評論:

#!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)] 
+0

我不認爲這是什麼OP後:所有的例子都有(循環)連續的數字。例如 – DSM

+0

^你需要考慮A3A1。 – sberry

+0

A1B3無效.... –

0

爲防萬一你想要一些可能與itertools.product一起工作的東西,你可以試試這個(如果它不符合你的'真實'輸入,那麼就試試這個(這是一個有趣的問題:))。這可以被包裝成更少的行,但它失去了很多的可讀性,所以希望這將是有點用的:

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 (i.e. ['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 

輸出:

['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']