如何生成不重复的 itertools 产品?
How to generate itertools product without duplicates?
我想我列出了一个错误的例子,对此我深表歉意,已经用另一个例子重新编辑了这个,请看这个版本。
我知道有一个非常相似的问题:Itertools product without repeating duplicates
但我有一些东西 different.For 示例:
a = ['add', 'sub']
b = [2,3, 'a', 'b']
c = [1,3, 'a', 'c']
list(it.product(a, b, c)) # result is:[('add', 2, 1),('add', 2, 3),('add', 2, 'a'), ('add', 2, 'c'),
#('add', 3, 1),('add', 3, 3),('add', 3, 'a'),('add', 3, 'c'),('add', 'a', 1),('add', 'a', 3),
#('add', 'a', 'a'),('add', 'a', 'c'), ('add', 'b', 1),('add', 'b', 3),('add', 'b', 'a'),
#('add', 'b', 'c'),('sub', 2, 1),('sub', 2, 3),('sub', 2, 'a'),('sub', 2, 'c'),('sub', 3, 1),
#('sub', 3, 3),('sub', 3, 'a'),('sub', 3, 'c'),('sub', 'a', 1),('sub', 'a', 3),('sub', 'a', 'a'),
#('sub', 'a', 'c'),('sub', 'b', 1),('sub', 'b', 3),('sub', 'b', 'a'),('sub', 'b', 'c')]
为结果:
我不想添加 (a,a),因为第一个值 == 第二个值
我只想保留 add(3,a) add(a,3) 中的 1 个,因为它是对称的。
我的示例只包含两个列表,但我可能会使用 5 个或更多列表来生成产品。
我不能使用组合,因为:
product(['add', 'sub', 1,2,3, 'a','b', 'c'], repeat=3) 是与产品不同(['add', 'sub'], [2,3, 'a', 'b'], [1,3, 'a', 'c'])
产品中的东西(['add', 'sub', 1,2,3, 'a','b', 'c'], 重复=3 ) 不适合我。
我想要一个快速的方法,因为我的程序对时间很敏感。
有人可以帮忙吗?
既然你已经把它转换成一个列表,你可以做一个列表理解来过滤掉0索引值等于1索引值的元组。
filtered_list = [(a, b) for a, b in unfiltered_list if a != b]
def filter_symmetry(_list):
checked_elements = []
if not len(_list):
return
for a, b in _list:
if (b, a) not in checked_elements:
checked_elements.append((a, b))
return checked_elements
filtered_list = filter_symmetry(filtered_list)
我想这就是你想要做的。
应该这样做:
import itertools
def generate_without_duplicates(*inputs):
seen = set()
for prod in itertools.product(*inputs):
prod_set = frozenset(prod)
if len(prod_set) == 1: # all items are the same
continue
if prod_set not in seen:
seen.add(prod_set)
yield prod
a = [1, 2, 3]
b = [2, 3, 4]
for val in generate_without_duplicates(a, b):
print(val)
输出为
(1, 2)
(1, 3)
(1, 4)
(2, 3)
(2, 4)
(3, 4)
您可以采用 itertools.product
的实现,对其进行调整以使其符合您的要求:
def product_without_dupl(*args, repeat=1):
pools = [tuple(pool) for pool in args] * repeat
result = [[]]
for pool in pools:
result = [x+[y] for x in result for y in pool if y not in x] # here we added condition
result = set(list(map(lambda x: tuple(sorted(x)), result))) # to remove symmetric duplicates
for prod in result:
yield tuple(prod)
来源:
https://docs.python.org/3/library/itertools.html#itertools.product
那么结果:
a = [1,2,3]
b = [2,3,4]
for el in product_without_dupl(a,b):
print(el)
#outputs:
(2, 4)
(1, 2)
(3, 4)
(1, 4)
(2, 3)
(1, 3)
我想我列出了一个错误的例子,对此我深表歉意,已经用另一个例子重新编辑了这个,请看这个版本。
我知道有一个非常相似的问题:Itertools product without repeating duplicates
但我有一些东西 different.For 示例:
a = ['add', 'sub']
b = [2,3, 'a', 'b']
c = [1,3, 'a', 'c']
list(it.product(a, b, c)) # result is:[('add', 2, 1),('add', 2, 3),('add', 2, 'a'), ('add', 2, 'c'),
#('add', 3, 1),('add', 3, 3),('add', 3, 'a'),('add', 3, 'c'),('add', 'a', 1),('add', 'a', 3),
#('add', 'a', 'a'),('add', 'a', 'c'), ('add', 'b', 1),('add', 'b', 3),('add', 'b', 'a'),
#('add', 'b', 'c'),('sub', 2, 1),('sub', 2, 3),('sub', 2, 'a'),('sub', 2, 'c'),('sub', 3, 1),
#('sub', 3, 3),('sub', 3, 'a'),('sub', 3, 'c'),('sub', 'a', 1),('sub', 'a', 3),('sub', 'a', 'a'),
#('sub', 'a', 'c'),('sub', 'b', 1),('sub', 'b', 3),('sub', 'b', 'a'),('sub', 'b', 'c')]
为结果:
我不想添加 (a,a),因为第一个值 == 第二个值
我只想保留 add(3,a) add(a,3) 中的 1 个,因为它是对称的。
我的示例只包含两个列表,但我可能会使用 5 个或更多列表来生成产品。
我不能使用组合,因为:
product(['add', 'sub', 1,2,3, 'a','b', 'c'], repeat=3) 是与产品不同(['add', 'sub'], [2,3, 'a', 'b'], [1,3, 'a', 'c'])
产品中的东西(['add', 'sub', 1,2,3, 'a','b', 'c'], 重复=3 ) 不适合我。
我想要一个快速的方法,因为我的程序对时间很敏感。
有人可以帮忙吗?
既然你已经把它转换成一个列表,你可以做一个列表理解来过滤掉0索引值等于1索引值的元组。
filtered_list = [(a, b) for a, b in unfiltered_list if a != b]
def filter_symmetry(_list):
checked_elements = []
if not len(_list):
return
for a, b in _list:
if (b, a) not in checked_elements:
checked_elements.append((a, b))
return checked_elements
filtered_list = filter_symmetry(filtered_list)
我想这就是你想要做的。
应该这样做:
import itertools
def generate_without_duplicates(*inputs):
seen = set()
for prod in itertools.product(*inputs):
prod_set = frozenset(prod)
if len(prod_set) == 1: # all items are the same
continue
if prod_set not in seen:
seen.add(prod_set)
yield prod
a = [1, 2, 3]
b = [2, 3, 4]
for val in generate_without_duplicates(a, b):
print(val)
输出为
(1, 2)
(1, 3)
(1, 4)
(2, 3)
(2, 4)
(3, 4)
您可以采用 itertools.product
的实现,对其进行调整以使其符合您的要求:
def product_without_dupl(*args, repeat=1):
pools = [tuple(pool) for pool in args] * repeat
result = [[]]
for pool in pools:
result = [x+[y] for x in result for y in pool if y not in x] # here we added condition
result = set(list(map(lambda x: tuple(sorted(x)), result))) # to remove symmetric duplicates
for prod in result:
yield tuple(prod)
来源: https://docs.python.org/3/library/itertools.html#itertools.product
那么结果:
a = [1,2,3]
b = [2,3,4]
for el in product_without_dupl(a,b):
print(el)
#outputs:
(2, 4)
(1, 2)
(3, 4)
(1, 4)
(2, 3)
(1, 3)