生成两个列表的所有组合,并在python中一一输出
Generating all the combinations of two lists and output them one by one in python
我有两个列表
[1, 3, 4] [7, 8]
我想生成两个列表的所有组合,从最小的组合开始,如 17,18,37,38,47,48,137,138,147,148......178,378....
现在对于每个组合,我必须测试它在其他地方的存在,如果我发现该组合存在,那么我将停止组合生成。例如,如果我看到 17
存在,那么我将不会生成其他组合。同样,如果我发现 48
存在,那么我将不会生成后面的组合。
这是一个非常丑陋的算法,但它对我有用。它也不是非常昂贵(当然,期望用 itertools.combinations(a, i)... 生成所有组合):
import itertools
def all_combs(a):
to_return = []
temp = []
for i in a:
temp.append(i)
to_return.append(temp)
for i in range(2, len(a) + 1):
temp = []
for j in itertools.combinations(a, i):
s = ""
for k in j:
s = s + str(k)
temp.append(int(s)) #Get all values from the list permutation
to_return.append(temp)
print(to_return)
return to_return
def all_perm(a, b):
a_combs = all_combs(a)
b_combs = all_combs(b)
to_return = []
for i in a_combs:
for j in b_combs:
for k in i:
for l in j:
to_return.append(10**len(str(l)) * k + l)
to_return.sort()
for i in to_return:
yield i
编辑:修复了未正确读取多位数值的错误
编辑:使函数充当生成器
编辑:修复了涉及数字的错误(通过添加排序...)
编辑:这是一个非常出色的实现,它更符合生成器风格。它仍然不完美,但它应该在一般情况下提供良好的加速:
import itertools
def add_to_dict(dict, length, num):
if not length in dict:
dict[length] = []
dict[length].append(num)
def sum_to_val(val):
to_return = []
for i in range(1, val):
to_return.append([i, val-i])
return to_return
def all_combs(a):
to_return = {}
for i in a:
add_to_dict(to_return, len(str(i)), i)
for i in range(2, len(a) + 1):
for j in itertools.combinations(a, i):
s = ""
for k in j:
s = s + str(k)
add_to_dict(to_return, len(s), int(s)) #Get all values from the list permutation
return to_return
def all_perm(a, b):
a_combs = all_combs(a)
b_combs = all_combs(b)
for val in range(max(a_combs.keys())+max(b_combs.keys())+1):
to_return = []
sums = sum_to_val(val)
for i in sums:
if not(i[0] in a_combs and i[1] in b_combs):
continue
for j in a_combs[i[0]]:
for k in b_combs[i[1]]:
to_return.append(10**len(str(k)) * j + k)
to_return.sort()
for i in to_return:
yield i
我有两个列表
[1, 3, 4] [7, 8]
我想生成两个列表的所有组合,从最小的组合开始,如 17,18,37,38,47,48,137,138,147,148......178,378....
现在对于每个组合,我必须测试它在其他地方的存在,如果我发现该组合存在,那么我将停止组合生成。例如,如果我看到 17
存在,那么我将不会生成其他组合。同样,如果我发现 48
存在,那么我将不会生成后面的组合。
这是一个非常丑陋的算法,但它对我有用。它也不是非常昂贵(当然,期望用 itertools.combinations(a, i)... 生成所有组合):
import itertools
def all_combs(a):
to_return = []
temp = []
for i in a:
temp.append(i)
to_return.append(temp)
for i in range(2, len(a) + 1):
temp = []
for j in itertools.combinations(a, i):
s = ""
for k in j:
s = s + str(k)
temp.append(int(s)) #Get all values from the list permutation
to_return.append(temp)
print(to_return)
return to_return
def all_perm(a, b):
a_combs = all_combs(a)
b_combs = all_combs(b)
to_return = []
for i in a_combs:
for j in b_combs:
for k in i:
for l in j:
to_return.append(10**len(str(l)) * k + l)
to_return.sort()
for i in to_return:
yield i
编辑:修复了未正确读取多位数值的错误 编辑:使函数充当生成器 编辑:修复了涉及数字的错误(通过添加排序...)
编辑:这是一个非常出色的实现,它更符合生成器风格。它仍然不完美,但它应该在一般情况下提供良好的加速:
import itertools
def add_to_dict(dict, length, num):
if not length in dict:
dict[length] = []
dict[length].append(num)
def sum_to_val(val):
to_return = []
for i in range(1, val):
to_return.append([i, val-i])
return to_return
def all_combs(a):
to_return = {}
for i in a:
add_to_dict(to_return, len(str(i)), i)
for i in range(2, len(a) + 1):
for j in itertools.combinations(a, i):
s = ""
for k in j:
s = s + str(k)
add_to_dict(to_return, len(s), int(s)) #Get all values from the list permutation
return to_return
def all_perm(a, b):
a_combs = all_combs(a)
b_combs = all_combs(b)
for val in range(max(a_combs.keys())+max(b_combs.keys())+1):
to_return = []
sums = sum_to_val(val)
for i in sums:
if not(i[0] in a_combs and i[1] in b_combs):
continue
for j in a_combs[i[0]]:
for k in b_combs[i[1]]:
to_return.append(10**len(str(k)) * j + k)
to_return.sort()
for i in to_return:
yield i