简体   繁体   中英

How to get a combination of values from multiple list of items with varying length in Python 3.x?

Below is are the lists that I have -

hosts = ['a', 'b', 'c', 'd']
ips = ["10.0.0.0", "10.0.0.1", "10.0.0.2"]
paths = [["abc", "xyz"], "def", "klm"]
names = ["test1", "test2", "test1"]

Required output ->

[('a', '10.0.0.0', "abc", "test1"), ('a', '10.0.0.0', "xyz", "test1"), ('a', '10.0.0.1', "def", "test2"),  ('a', '10.0.0.2', "klm", "test1")] and so on for b, c and d values in hosts.

Note: ips & names are normal lists with equal length. Paths can be nested list but overall length would be same as ips & names. However, the lengths of ips, paths and names need not match with hosts (which is not a nested list).

Can someone suggest me a idea for this other than redundant writing of for loops and also Zip doesn't work because of varying length of lists. Thank you in advance.

Are you looking for this?

from itertools import product

def flatten(ips, paths, names):
    result = []
    for i, p, n in zip(ips, paths, names):
        if isinstance(p, list):
            result.extend(product([i], p, [n]))
        else:
            result.append((i, p, n))
    return result


all_outputs = []
for entry in product(hosts, flatten(ips, paths, names)):
    output = [entry[0]]
    output.extend(*entry[1:])
    all_outputs.append(output)

Output

[['a', '10.0.0.0', 'abc', 'test1'],
 ['a', '10.0.0.0', 'xyz', 'test1'],
 ['a', '10.0.0.1', 'def', 'test2'],
 ['a', '10.0.0.2', 'klm', 'test1'],
 ['b', '10.0.0.0', 'abc', 'test1'],
 ['b', '10.0.0.0', 'xyz', 'test1'],
 ['b', '10.0.0.1', 'def', 'test2'],
 ['b', '10.0.0.2', 'klm', 'test1'],
 ['c', '10.0.0.0', 'abc', 'test1'],
 ['c', '10.0.0.0', 'xyz', 'test1'],
 ['c', '10.0.0.1', 'def', 'test2'],
 ['c', '10.0.0.2', 'klm', 'test1'],
 ['d', '10.0.0.0', 'abc', 'test1'],
 ['d', '10.0.0.0', 'xyz', 'test1'],
 ['d', '10.0.0.1', 'def', 'test2'],
 ['d', '10.0.0.2', 'klm', 'test1']]

Not sure of straight-forward way. Using loops:

hosts = ['a', 'b', 'c', 'd']
ips = ["10.0.0.0", "10.0.0.1", "10.0.0.2"]
paths = [["abc", "xyz"], "def", "klm"]
names = ["test1", "test2", "test1"]

final_list = []
for elem in hosts:
  for i in range(len(ips)):
    if isinstance(paths[i], list):
      for j in range(len(paths[i])):
        final_list.append((elem, ips[i], paths[i][j], names[i]))
    elif isinstance(paths[i], str):
      final_list.append((elem, ips[i], paths[i], names[i]))

print(final_list)

You can use recursion with a generator:

def combos(d, c = []):
  if not d:
     yield tuple(c)
  else:
     for i in [j for k in d[0] for j in (k if isinstance(k, list) else [k])]:
        yield from combos(d[1:], c+[i])
        

hosts = ['a', 'b', 'c', 'd']
ips = ["10.0.0.0", "10.0.0.1", "10.0.0.2"]
paths = [["abc", "xyz"], "def", "klm"]
names = ["test1", "test2", "test1"]
print(list(combos([hosts, ips, paths, names])))

Output:

[('a', '10.0.0.0', 'abc', 'test1'), ('a', '10.0.0.0', 'abc', 'test2'), ('a', '10.0.0.0', 'abc', 'test1'), ('a', '10.0.0.0', 'xyz', 'test1'), ('a', '10.0.0.0', 'xyz', 'test2'), ('a', '10.0.0.0', 'xyz', 'test1'), ('a', '10.0.0.0', 'def', 'test1'), ('a', '10.0.0.0', 'def', 'test2'), ('a', '10.0.0.0', 'def', 'test1'), ('a', '10.0.0.0', 'klm', 'test1'), ('a', '10.0.0.0', 'klm', 'test2'), ('a', '10.0.0.0', 'klm', 'test1'), ('a', '10.0.0.1', 'abc', 'test1'), ('a', '10.0.0.1', 'abc', 'test2'), ('a', '10.0.0.1', 'abc', 'test1'), ('a', '10.0.0.1', 'xyz', 'test1'), ('a', '10.0.0.1', 'xyz', 'test2'), ('a', '10.0.0.1', 'xyz', 'test1'), ('a', '10.0.0.1', 'def', 'test1'), ('a', '10.0.0.1', 'def', 'test2'), ('a', '10.0.0.1', 'def', 'test1'), ('a', '10.0.0.1', 'klm', 'test1'), ('a', '10.0.0.1', 'klm', 'test2'), ('a', '10.0.0.1', 'klm', 'test1'), ('a', '10.0.0.2', 'abc', 'test1'), ('a', '10.0.0.2', 'abc', 'test2'), ('a', '10.0.0.2', 'abc', 'test1'), ('a', '10.0.0.2', 'xyz', 'test1'), ('a', '10.0.0.2', 'xyz', 'test2'), ('a', '10.0.0.2', 'xyz', 'test1'), ('a', '10.0.0.2', 'def', 'test1'), ('a', '10.0.0.2', 'def', 'test2'), ('a', '10.0.0.2', 'def', 'test1'), ('a', '10.0.0.2', 'klm', 'test1'), ('a', '10.0.0.2', 'klm', 'test2'), ('a', '10.0.0.2', 'klm', 'test1'), ('b', '10.0.0.0', 'abc', 'test1'), ('b', '10.0.0.0', 'abc', 'test2'), ('b', '10.0.0.0', 'abc', 'test1'), ('b', '10.0.0.0', 'xyz', 'test1'), ('b', '10.0.0.0', 'xyz', 'test2'), ('b', '10.0.0.0', 'xyz', 'test1'), ('b', '10.0.0.0', 'def', 'test1'), ('b', '10.0.0.0', 'def', 'test2'), ('b', '10.0.0.0', 'def', 'test1'), ('b', '10.0.0.0', 'klm', 'test1'), ('b', '10.0.0.0', 'klm', 'test2'), ('b', '10.0.0.0', 'klm', 'test1'), ('b', '10.0.0.1', 'abc', 'test1'), ('b', '10.0.0.1', 'abc', 'test2'), ('b', '10.0.0.1', 'abc', 'test1'), ('b', '10.0.0.1', 'xyz', 'test1'), ('b', '10.0.0.1', 'xyz', 'test2'), ('b', '10.0.0.1', 'xyz', 'test1'), ('b', '10.0.0.1', 'def', 'test1'), ('b', '10.0.0.1', 'def', 'test2'), ('b', '10.0.0.1', 'def', 'test1'), ('b', '10.0.0.1', 'klm', 'test1'), ('b', '10.0.0.1', 'klm', 'test2'), ('b', '10.0.0.1', 'klm', 'test1'), ('b', '10.0.0.2', 'abc', 'test1'), ('b', '10.0.0.2', 'abc', 'test2'), ('b', '10.0.0.2', 'abc', 'test1'), ('b', '10.0.0.2', 'xyz', 'test1'), ('b', '10.0.0.2', 'xyz', 'test2'), ('b', '10.0.0.2', 'xyz', 'test1'), ('b', '10.0.0.2', 'def', 'test1'), ('b', '10.0.0.2', 'def', 'test2'), ('b', '10.0.0.2', 'def', 'test1'), ('b', '10.0.0.2', 'klm', 'test1'), ('b', '10.0.0.2', 'klm', 'test2'), ('b', '10.0.0.2', 'klm', 'test1'), ('c', '10.0.0.0', 'abc', 'test1'), ('c', '10.0.0.0', 'abc', 'test2'), ('c', '10.0.0.0', 'abc', 'test1'), ('c', '10.0.0.0', 'xyz', 'test1'), ('c', '10.0.0.0', 'xyz', 'test2'), ('c', '10.0.0.0', 'xyz', 'test1'), ('c', '10.0.0.0', 'def', 'test1'), ('c', '10.0.0.0', 'def', 'test2'), ('c', '10.0.0.0', 'def', 'test1'), ('c', '10.0.0.0', 'klm', 'test1'), ('c', '10.0.0.0', 'klm', 'test2'), ('c', '10.0.0.0', 'klm', 'test1'), ('c', '10.0.0.1', 'abc', 'test1'), ('c', '10.0.0.1', 'abc', 'test2'), ('c', '10.0.0.1', 'abc', 'test1'), ('c', '10.0.0.1', 'xyz', 'test1'), ('c', '10.0.0.1', 'xyz', 'test2'), ('c', '10.0.0.1', 'xyz', 'test1'), ('c', '10.0.0.1', 'def', 'test1'), ('c', '10.0.0.1', 'def', 'test2'), ('c', '10.0.0.1', 'def', 'test1'), ('c', '10.0.0.1', 'klm', 'test1'), ('c', '10.0.0.1', 'klm', 'test2'), ('c', '10.0.0.1', 'klm', 'test1'), ('c', '10.0.0.2', 'abc', 'test1'), ('c', '10.0.0.2', 'abc', 'test2'), ('c', '10.0.0.2', 'abc', 'test1'), ('c', '10.0.0.2', 'xyz', 'test1'), ('c', '10.0.0.2', 'xyz', 'test2'), ('c', '10.0.0.2', 'xyz', 'test1'), ('c', '10.0.0.2', 'def', 'test1'), ('c', '10.0.0.2', 'def', 'test2'), ('c', '10.0.0.2', 'def', 'test1'), ('c', '10.0.0.2', 'klm', 'test1'), ('c', '10.0.0.2', 'klm', 'test2'), ('c', '10.0.0.2', 'klm', 'test1'), ('d', '10.0.0.0', 'abc', 'test1'), ('d', '10.0.0.0', 'abc', 'test2'), ('d', '10.0.0.0', 'abc', 'test1'), ('d', '10.0.0.0', 'xyz', 'test1'), ('d', '10.0.0.0', 'xyz', 'test2'), ('d', '10.0.0.0', 'xyz', 'test1'), ('d', '10.0.0.0', 'def', 'test1'), ('d', '10.0.0.0', 'def', 'test2'), ('d', '10.0.0.0', 'def', 'test1'), ('d', '10.0.0.0', 'klm', 'test1'), ('d', '10.0.0.0', 'klm', 'test2'), ('d', '10.0.0.0', 'klm', 'test1'), ('d', '10.0.0.1', 'abc', 'test1'), ('d', '10.0.0.1', 'abc', 'test2'), ('d', '10.0.0.1', 'abc', 'test1'), ('d', '10.0.0.1', 'xyz', 'test1'), ('d', '10.0.0.1', 'xyz', 'test2'), ('d', '10.0.0.1', 'xyz', 'test1'), ('d', '10.0.0.1', 'def', 'test1'), ('d', '10.0.0.1', 'def', 'test2'), ('d', '10.0.0.1', 'def', 'test1'), ('d', '10.0.0.1', 'klm', 'test1'), ('d', '10.0.0.1', 'klm', 'test2'), ('d', '10.0.0.1', 'klm', 'test1'), ('d', '10.0.0.2', 'abc', 'test1'), ('d', '10.0.0.2', 'abc', 'test2'), ('d', '10.0.0.2', 'abc', 'test1'), ('d', '10.0.0.2', 'xyz', 'test1'), ('d', '10.0.0.2', 'xyz', 'test2'), ('d', '10.0.0.2', 'xyz', 'test1'), ('d', '10.0.0.2', 'def', 'test1'), ('d', '10.0.0.2', 'def', 'test2'), ('d', '10.0.0.2', 'def', 'test1'), ('d', '10.0.0.2', 'klm', 'test1'), ('d', '10.0.0.2', 'klm', 'test2'), ('d', '10.0.0.2', 'klm', 'test1')]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM