Python是给定列表的一些特殊产品

Python是给定列表的一些特殊产品,python,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

我想为给定列表中可能的产品找到一种方法。下面,我举一个例子

到目前为止,我尝试了以下方法:

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。

您可以通过

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

然后,取两个连续列表的乘积应该会得到你想要的(如果我正确理解你的问题…)

根据您当前的列表,如果您只想获得所有排列并在事后过滤不受欢迎的内容,那么没有太多的值需要删除。懒洋洋地这样做,你过滤的东西会比你保留的东西少很多。(为了透明,我将使用列表理解–在实际代码中将其转换为生成器表达式。)

更新以回答John的评论: 假设每个状态具有相同的序列大小:

>>> 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]
更新以概括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)]
这将产生:

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

它输出相同的东西。

如果您想要一些可以与
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']

这可能需要手动编写,并带有一个循环。用英语把它分解(就像你已经开始的那样),然后从那里开始。祝你好运,我有点糊涂了。。。你说它不能以
'B2'
开头,但是
'B2A3'
是有效的…哦,对不起,我误解了你的第一个问题。它可以从B1和B2开始。所谓“A3跟在A1、B1、C1或D1后面”,你的意思是完全相反的,即“A3跟在A1、B1、C1或D1后面”?我的意思是像“A3A1”、“A3B1”、“A3C1”、“A3D1”……我不认为这就是OP的目的:所有的例子都有数字(按周期排列)你需要考虑A3A1。啊,对不起,我不理解这些要求。更新–更好吗?没问题,更好。索引是两行,例如A15,您将如何更新代码?@JohnSmith您对问题的描述不能解释A3A0。只有当
initial_list=['A0','A1','A2','A3','B0','B1',…]时,A3A0才会发生
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']