C. *_*ppy 6 python optimization python-itertools
我想从两个列表中有效地生成元素对,这些元素等于它们的笛卡尔积,并省略了一些元素。每个列表中的元素都是唯一的。
下面的代码完全满足了需要,但我希望通过替换循环来优化它。
详细内容请参见代码中的注释。
任何意见,将不胜感激。
from itertools import product
from pprint import pprint as pp
def pairs(list1, list2):
""" Return all combinations (x,y) from list1 and list2 except:
1. Omit combinations (x,y) where x==y """
tuples = filter(lambda t: t[0] != t[1], product(list1,list2))
""" 2. Include only one of the combinations (x,y) and (y,x) """
result = []
for t in tuples:
if not (t[1], t[0]) in result:
result.append(t)
return result
list1 = ['A', 'B', 'C']
list2 = ['A', 'D', 'E']
pp(pairs(list1, list1)) # Test a list with itself
pp(pairs(list1, list2)) # Test two lists with some common elements
Run Code Online (Sandbox Code Playgroud)
输出
[('A', 'B'), ('A', 'C'), ('B', 'C')]
[('A', 'D'),
('A', 'E'),
('B', 'A'),
('B', 'D'),
('B', 'E'),
('C', 'A'),
('C', 'D'),
('C', 'E')]
Run Code Online (Sandbox Code Playgroud)
比您的答案基准中最快的速度快大约 5-6 倍。我构建了出现在两个列表或仅一个列表中的一组值,并将它们适当地组合起来,而无需进一步过滤。
from itertools import product, combinations
def pairs(list1, list2):
a = {*list1}
b = {*list2}
ab = a & b
return [
*product(a, b-a),
*product(a-b, ab),
*combinations(ab, 2)
]
Run Code Online (Sandbox Code Playgroud)
您还可以将其设为迭代器(因为与以前的解决方案不同,我不需要存储已生成的对来过滤更多的对):
from itertools import product, combinations, chain
def pairs(list1, list2):
a = {*list1}
b = {*list2}
ab = a & b
return chain(
product(a, b-a),
product(a-b, ab),
combinations(ab, 2)
)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
106 次 |
| 最近记录: |