【问题标题】:merge two sets with considering the order of each one (in Python)合并两个集合并考虑每个集合的顺序(在 Python 中)
【发布时间】:2019-09-10 03:08:35
【问题描述】:

我有两个变量 i,j,它们显示两个集合 1 和 2 的长度,例如 len(one)=i 和 len(two)=j。现在,我想合并这两个集合,以使每个集合具有有序排列。我还需要在 Python 中为每个新集合建立索引。

例如: 一个包含前 i 个大写字母,两个包含小写字母

 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
  • 集合在 Python 中是无序的,因此您无法按照预期输出的建议保留 ABCab 的顺序。将您的输入更改为列表,然后您就会有一个有效的问题。

标签: python set


【解决方案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 的顺序。此处给出的示例假定您的输入和输出是列表。

【讨论】:

  • 非常感谢@blhsing。我有另一个问题。如果集合中的字母数量是可变的,我该怎么办?
  • 很高兴能提供帮助。我的回答没有对列表中的字母数量做出任何假设,因此您可以使用任意数量的字母。另外,如果您认为此答案正确,您能否将其标记为已接受? (点击答案旁边的灰色复选标记。)
  • 我已经标记过了。谢谢你。我的意思是如何将字母假设为像 i 这样的变量?
  • 我认为您没有将答案标记为已接受,因为如果您这样做了,答案旁边的灰色复选标记会变成绿色。至于将字母集设为变量,您可以将其设为您在问题中发布的 onetwo 变量。
  • 我刚刚做到了。对不起,我是这个网站的新手。至于我的问题,我的意思是在我的代码的另一部分中,我得到了 i 和 j 的字母数 1 和 2。
【解决方案2】:

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

【讨论】:

  • 生成所有可能的排列并丢弃大部分排列是浪费和低效的,它们的顺序与输入的顺序不匹配。暴力破解解决方案只能作为最后的手段。
猜你喜欢
  • 2016-09-22
  • 1970-01-01
  • 1970-01-01
  • 2016-06-05
  • 1970-01-01
  • 2023-03-07
  • 2017-10-05
  • 2014-05-29
  • 2019-01-28
相关资源
最近更新 更多