如何解决获取 m 个列表的 r 长度元组组合,任何列表中不超过一个元素,并且 r < m 过滤itertools.combinations的输出
在下面的示例中,我有 m = 3
列表,我计算了大小 r = 2
的组合。
import itertools
a = ['a1','a2','a3']
b = ['b1','b2','b3']
c = ['c1','c2','c3']
print(list(itertools.combinations(itertools.chain(a,b,c),2)))
输出:
[('a1','a2'),('a1','a3'),'b1'),'b2'),'b3'),'c1'),'c2'),'c3'),('a2',('a3',('b1',('b2',('b3',('c1',('c2','c3')]
问题:
我不想要来自同一个列表的组合。例如,应删除 ('a1','a2')
和 ('a1','a3')
。
解决方法
稍微解释一下 Mateen 的答案,您可以先在外循环中以 r
的方式选择 m choose r
集,然后在内循环中迭代 r
集的乘积。输出的顺序可能与其他方法不同。
lsts = [a,b,c]
def f(lsts,r):
"""
lsts :: [[a]]
r :: Integer
Generate r-tuples with at most one element coming from
each member of lsts.
"""
m = len(lsts)
assert m >= r
for xs in itertools.combinations(lsts,r):
for x in itertools.product(*xs):
yield x
,
这可能是一个周转的解决方案,但您可能希望修改作为输出获得的列表以仅保留所需的值。
[i for i in a if i[0][0]!=i[1][0]]
a
是您的列表a = list(itertools.combinations(itertools.chain(a,c),2))
过滤itertools.combinations
的输出
这不一定是最优雅或最高效的解决方案,但它确实有效。
def is_unique(comb,lookup):
xs = [lookup[x] for x in comb]
return len(xs) == len(set(xs))
def combine(args,r):
lookup = {x: i for i,xs in enumerate(args) for x in xs}
return (
comb
for comb in itertools.combinations(itertools.chain(*args),r)
if is_unique(comb,lookup)
)
>>> list(combine((a,2))
[('a1','b1'),('a1','b2'),'b3'),# (a1,b*)
('a1','c1'),'c2'),'c3'),c*)
('a2',('a2',# (a2,b*)
('a2',c*)
('a3',('a3',# (a3,b*)
('a3',c*)
('b1',('b1',# (b1,c*)
('b2',('b2',# (b2,c*)
('b3',('b3','c3')] # (b3,c*)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。