重复但不加倍的列表的所有排列

Posted

技术标签:

【中文标题】重复但不加倍的列表的所有排列【英文标题】:ALL permutations of a list with repetition but not doubles 【发布时间】:2017-10-30 05:15:15 【问题描述】:

我见过类似但不一样的:here。 我绝对想要所有列表元素的排列,而不是组合。我的不同,因为 a,b,c 的 itertools 排列返回 abc 但不返回 aba(非常接近)。 我怎样才能得到像 aba 一样的结果?

('a',)     <-excellent
('b',)     <-excellent
('c',)     <-excellent
('a', 'b') <-excellent
('a', 'c') <-excellent
('b', 'a') <-excellent
('b', 'c') <-excellent
('c', 'a') <-excellent
('c', 'b') <-excellent
('a', 'b', 'c') <-- I need a,b,a
('a', 'c', 'b') <-- I need a,c,a
('b', 'a', 'c') <-- I need b,a,b... you get the idea

哦,排列的最大长度(python.org itertools 中的“r”)等于 len(list),我不想包含诸如 aab 或 abb ...或 abba 之类的“双精度”:P该列表可以是任意长度。

import itertools
from itertools import product
my_list = ["a","b","c"]
#print list(itertools.permutations(my_list, 1))
#print list(itertools.permutations(my_list, 2))
#print list(itertools.permutations(my_list, 3)) <-- this *ALMOST* works

我将以上内容组合成一个for循环

def all_combinations(varsxx):
    repeat = 1
    all_combinations_result = []
    for item in varsxx:
        if repeat <= len(varsxx):
            all_combinations_result.append(list(itertools.permutations(varsxx, repeat)))
        repeat += 1
    return all_combinations_result

作为参考,当我在纸上这样做时,我得到了 21 个结果。

将字符串列表转换为数字列表也有什么好处。我的想法是,对于排列工具来说,数字会更容易使用。字符串可能是 10 到 50 个字符..ish。

【问题讨论】:

你需要更准确地描述你到底想要什么。 【参考方案1】:

即使你“肯定想要排列”,听起来你并不真的想要那个,你实际上想要你的序列的笛卡尔积与它自己从 1 到 len(sequence) 次,结果与相邻的相等元素过滤掉。

类似:

In [16]: from itertools import product

In [17]: def has_doubles(x): return any(i==j for i,j in zip(x, x[1:]))

In [18]: seq = ["a","b","c"]

In [19]: [x for n in range(len(seq)) for x in product(seq, repeat=n+1) 
            if not has_doubles(x)]
Out[19]: 
[('a',),
 ('b',),
 ('c',),
 ('a', 'b'),
 ('a', 'c'),
 ('b', 'a'),
 ('b', 'c'),
 ('c', 'a'),
 ('c', 'b'),
 ('a', 'b', 'a'),
 ('a', 'b', 'c'),
 ('a', 'c', 'a'),
 ('a', 'c', 'b'),
 ('b', 'a', 'b'),
 ('b', 'a', 'c'),
 ('b', 'c', 'a'),
 ('b', 'c', 'b'),
 ('c', 'a', 'b'),
 ('c', 'a', 'c'),
 ('c', 'b', 'a'),
 ('c', 'b', 'c')]

In [20]: len(_)
Out[20]: 21

【讨论】:

太棒了,你把它钉在了一个! :) 代码第一次工作,双打已被删除,“产品”都在那里,计数是正确的,它也适用于更大的列表:) 钉 everything :) 非常感谢! 再次感谢您对此的帮助。我可以再请你帮忙吗?我需要 YIELD 来代替结果,但我试图修改它的尝试被证明是徒劳的。我需要“跨过”结果。 IE 得到结果 ('a',) 并使用它。然后转到 ('b',)

以上是关于重复但不加倍的列表的所有排列的主要内容,如果未能解决你的问题,请参考以下文章

生成具有重复元素的列表排列

从n个整数列表(可能长度不等)中进行所有可能的n个长度排列[重复]

如何生成排列而不生成重复结果但具有固定数量的字符Python [重复]

生成排列[重复]

列表元素的所有排列

获取字符串或组合的所有可能排列,包括 Java 中的重复字符