简体   繁体   中英

Nested loop in python to produce cartesian product

I am trying to loop through two list in python to get a output like this.

list1 = [a, b, c]
list2 = [1, 2, 3]

So it should loop for each value of list1 over list 2. list1[a] will loop 3 times over list2 and so on till it reaches c. However, I am not getting the desired output.

i=''
list1 = ['ABC ' + str(i)+ ' '+'1' + ' ' + '5', 'CDE '+ str(i)+ ' '+  '1'+ ' ' + '5']
list2=['123','234','456']
for c in list1:
         for i in list2:
               print c

Output:

ABC  1 5
ABC  1 5
ABC  1 5
CDE  1 5
CDE  1 5
CDE  1 5

Desired out put should be like below:

ABC 123 1 5
CDE 123 1 5
ABC 234 1 5
CDE 234 1 5
ABC 456 1 5
CDE 456 1 5

Please guide me what I am missing here, am new with this.

You need to interpolate the list2 value inside the loop. You could the itertools.product() function instead of nesting your loops; do swap the order of the lists if you want the values of list1 to alterate:

from itertools import product

list1 = ['ABC {} 1 5', 'CDE {} 1 5']
list2 = ['123','234','456']
for l2, l1 in product(list2, list1):
    print l1.format(l2)

The str.format() method fills the {} in the list1 strings with your l2 values, letting you avoid having to rebuild list2 from scratch each time:

>>> for l2, l1 in product(list2, list1):
...     print(l1.format(l2))
...
ABC 123 1 5
CDE 123 1 5
ABC 234 1 5
CDE 234 1 5
ABC 456 1 5
CDE 456 1 5

Another alternative is for list1 to contain tuples of values to be used, and only when printing you convert everything to one string by using print() as a function (Python 3, or a from __future__ import in Python 2):

from __future__ import print_function

list1 = [('ABC', 1, 5), ('CDE', 1, 5)]
list2 = ['123','234','456']
for l2, (a, b, c) in product(list2, list1):
    print(a, l2, b, c)

It depends on what else you want to do with the values produced.

Note that if the 1 and 5 numbers are otherwise unchanged between the values of list1 , there is no need at all to do a complicated dance with string templates or tuples. You'd just reference those inside the loop:

b, c = 1, 5
list1 = ['ABC', 'CDE']
list2 = ['123','234','456']
for l2, l1 in product(list2, list1):
    print '{} {} {} {}'.format(l1, l2, b, c)

I still used string formatting just to show another form of combining several values into one string.

You need to move the construction of list1 into your for loop. Reorganize your lines as follows:

list2 = ['123', '234', '456']

for i in list2:
    list1 = ['ABC ' + str(i) + ' ' + '1' + ' ' + '5',
             'CDE ' + str(i) + ' ' + '1' + ' ' + '5']
    for c in list1:
        print c

this will print

ABC 123 1 5
CDE 123 1 5
ABC 234 1 5
CDE 234 1 5
ABC 456 1 5
CDE 456 1 5

That being said, this can be improved using string formatting :

for i in list2:
    list1 = ['ABC {0} 1 5', 'CDE {0} 1 5']
    for c in list1:
        print c.format(i)

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