Python中考虑每个集合的顺序合并两个集合

3
我有两个变量 i 和 j,它们分别表示两个集合 one 和 two 的长度,例如 len(one)=i 和 len(two)=j。现在,我想将这两个集合合并,并按顺序列出每个集合的排列组合。我还需要在 Python 中为每个新集合编制索引。
例如: one 包含前 i 个大写字母,two 包含小写字母。
 len(one) = i  
    len(two) = j 
expected outputs = {'abABC...', 'aAbBC...', 'aABcC...', 'aABCb...',...}

我尝试了以下代码,但它没有起作用。如果有人能帮忙,我会很感激。
    from functools import reduce
    from itertools import combinations

    def assign(v, p):
        v[p[0]] = p[1]
        return v

    def interp(word1, word2, size):
        return (''.join(reduce(assign, zip(comb1, word1), zip(comb2, word2)))
                for comb1, comb2 in zip(combinations(range(size), len(word1)),
                                        combinations(range(size), len(word2))))

    print('\n'.join(interp("ABC", "ab", 5)))

不要使用reduce来产生副作用:reduce(assign) - juanpa.arrivillaga
2
集合在Python中是无序的,因此您无法像期望的输出那样保留ABCab的顺序。将输入更改为列表,然后您将拥有一个有效的问题。 - blhsing
2个回答

1
itertools 中借用partition配方:
one = set(['A', 'B', 'C'])
two = set(['a', 'b'])

from itertools import permutations, tee, filterfalse, chain

def partition(pred, iterable):
    'Use a predicate to partition entries into false entries and true entries'
    # partition(is_odd, range(10)) --> 0 2 4 6 8   and  1 3 5 7 9
    t1, t2 = tee(iterable)
    return filterfalse(pred, t1), filter(pred, t2)

iter_1 = ((i, 1) for i in one)
iter_2 = ((i, 2) for i in two)

for c in permutations(chain(iter_1, iter_2), 5):
    p1, p2 = map(list, partition(lambda k: k[1] == 1, c))
    if sorted(p1, key=lambda k: k[0]) == p1 and sorted(p2, key=lambda k: k[0]) == p2:
        print(''.join(i[0] for i in c))

输出:

ABCab
ABaCb
ABabC
AaBCb
AaBbC
AabBC
aABCb
aABbC
aAbBC
abABC

生成所有可能的排列,然后丢弃大部分不符合输入顺序的排列是低效和浪费的。暴力解决方案应该只作为最后的手段使用。 - blhsing

1
你可以使用一个函数,递归地将其中一个列表的第一项与剩余列表中的组合合并起来:
def merge(a, b):
    if a and b:
        for (first, *rest), other in (a, b), (b, a):
            yield from ([first, *merged] for merged in merge(rest, other))
    elif a or b:
        yield a or b

所以:
for combination in merge(['A', 'B', 'C'], ['a', 'b']):
    print(''.join(combination))

输出:

ABCab
ABabC
ABaCb
AabBC
AaBCb
AaBbC
abABC
aABCb
aABbC
aAbBC

请注意,在Python中,集合是无序的,因此,如果您的输入为集合,则无法按照您期望的输出方式保留ABCab 的顺序。这里给出的示例假定您的输入和输出是列表而不是集合。

我已经标记了。谢谢。我的意思是如何将字母视为变量,例如i? - Star
我认为你还没有将答案标记为已接受,因为如果你这样做了,答案旁边的灰色勾号就会变成绿色。至于将字母集合作为变量,你可以像你在问题中发布的 onetwo 变量一样制作它。 - blhsing
我看到了你更新的问题,但仅凭字母长度,你怎么知道它们是哪些字母?它们总是字母序列A、B、C等,一个大写,一个小写吗? - blhsing
实际上,它们不是字母。它们可以是任何一组对象。为了简化问题,我假设它们是两组字母,一组大写字母,一组小写字母。 - Star
我们可以假设我有两组对象,无论它们是什么,字母、数字等等... 我只知道它们的长度。我需要的是这两组对象的排列组合。 - Star
显示剩余10条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接