Python multi-layer for loop to recursion/iteration

scenes to be used

Enumeration combination:

The problem is this.

There are n lists, and one element is taken from each list. How many combinations are there?

E.g:

a = ['a1','a2']
b = ['b1','b2','b3']

The combined result is:

[
  ('a1','b1'),
  ('a1','b2'),
  ('a1','b3'),
  ('a2','b1'),
  ('a2','b2'),
  ('a2','b3')
]

There are only two lists to be combined

This situation is a simple traversal:

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
a = ['a1','a2']
b = ['b1','b2','b3']

res = []
for i in a:
  for j in b:
    res.append((i,j)])

print(res)

Expand to n

If you also use for loop nesting, the code is like this

a = ['a1','a2']
b = ['b1','b2','b3']

res = []
for i in a:
  for j in b:
    for k in c:
        ...
           ...

If it is n-layer, such code cannot be expressed.

We can first combine the first and second, and then take the combined result and the third combination, and so on...

As shown below:
Insert picture description here
The code is as follows:

Iteration

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
def merge(i,j):
  """
  i = "a"
  j = ("b","c")
  return: ("a","b","c")
  """
  res = []
  for p in (i,j):
    if isinstance(p,tuple):
      res.extend(p)
    else:
      res.append(p)
  return tuple(res)

def combineN(*args):
  target = args[0]
  for li in args[1:]:
    tmp = []
    for i in target:
      for j in li:
        tmp.append(merge(i,j))
    target = tmp
  return target

Recursion

def merge(i,j):
  """
  i = "a"
  j = ("b","c")
  return: ("a","b","c")
  """
  res = []
  for p in (i,j):
    if isinstance(p,tuple):
      res.extend(p)
    else:
      res.append(p)
  return tuple(res)

def combine2(a, b):
    res = []
    for i in a:
        for j in b:
            res.append(merge(i,j))
    return res

def combineNRecursion(*args):
  if len(args) == 2:
    return combine2(*args)

  return combine2(args[0],combineNRecursion(*args[1:]))

General multi-layer for loop to iteration

The iterative method used above is analyzed for specific problems, so is there a general conversion scheme? The answer is yes.

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
def combineN(*li):
    res = []
    # 相当于最内层循环执行的次数.
    total_times = reduce(lambda x, y: x*y, [len(item) for item in li])
    n = 0
    while n < total_times:
        tmp = n
        tem_res = []
        for i in range(len(li)):
            # 余数就是参与计算的元素的下标,商用于计算下一个列表参与元素的下标.
            tmp, cur = divmod(tmp, len(li[i]))
            tem_res.append(li[i][cur])
        res.append(tem_res)
        n += 1
    return res

res = combineN(["a1","a2"], ["b1", "b2"], ["c1", "c2"])
for i in res:
    print(i)

The output is as follows:

['a1', 'b1', 'c1']
['a2', 'b1', 'c1']
['a1', 'b2', 'c1']
['a2', 'b2', 'c1']
['a1', 'b1', 'c2']
['a2', 'b1', 'c2']
['a1', 'b2', 'c2']
['a2', 'b2', 'c2']

Guess you like

Origin blog.csdn.net/sinat_38682860/article/details/108711263