Search code examples
pythonlist-comprehensionpython-itertools

itertools.product using list comprehension


I want to use list comprehension, instead of itertools.product

def pr(l):
    return [''.join(i) for i in [(x,y) for x in l for y in l]]

operators = ['/','*','+','-']
pr(operators)

['//', '/*', '/+', '/-', '*/', '**', '*+', '*-', '+/', '+*', '++', '+-', '-/', '-*', '-+', '--']

This works, but I want to modify my function such that it returns combinations in pairs of repeat:

def pr(l, repeat=1):
   # list comprehension code here



o = ['/','*','+','-']

pr(operators, repeat=4)
pr(operators, repeat=3)

['////', '///*', '///+', '///-', '//*/', '//**', '//*+', '//*-', '//+/', '//+*', '//++', '//+-', '//-/', '//-*', '//-+', '//--', '/*//', '/*/*', '/*/+', '/*/-', '/**/', '/***', '/**+', '/**-', '/*+/', '/*+*', '/*++', '/*+-', '/*-/', '/*-*', '/*-+', '/*--', '/+//', '/+/*', '/+/+', '/+/-', '/+*/', '/+**', '/+*+', '/+*-', '/++/', '/++*', '/+++', '/++-', '/+-/', '/+-*', '/+-+', '/+--', '/-//', '/-/*', '/-/+', '/-/-', '/-*/', '/-**', '/-*+', '/-*-', '/-+/', '/-+*', '/-++', '/-+-', '/--/', '/--*', '/--+', '/---', '*///', '*//*', '*//+', '*//-', '*/*/', '*/**', '*/*+', '*/*-', '*/+/', '*/+*', '*/++', '*/+-', '*/-/', '*/-*', '*/-+', '*/--', '**//', '**/*', '**/+', '**/-', '***/', '****', '***+', '***-', '**+/', '**+*', '**++', '**+-', '**-/', '**-*', '**-+', '**--', '*+//', '*+/*', '*+/+', '*+/-', '*+*/', '*+**', '*+*+', '*+*-', '*++/', '*++*', '*+++', '*++-', '*+-/', '*+-*', '*+-+', '*+--', '*-//', '*-/*', '*-/+', '*-/-', '*-*/', '*-**', '*-*+', '*-*-', '*-+/', '*-+*', '*-++', '*-+-', '*--/', '*--*', '*--+', '*---', '+///', '+//*', '+//+', '+//-', '+/*/', '+/**', '+/*+', '+/*-', '+/+/', '+/+*', '+/++', '+/+-', '+/-/', '+/-*', '+/-+', '+/--', '+*//', '+*/*', '+*/+', '+*/-', '+**/', '+***', '+**+', '+**-', '+*+/', '+*+*', '+*++', '+*+-', '+*-/', '+*-*', '+*-+', '+*--', '++//', '++/*', '++/+', '++/-', '++*/', '++**', '++*+', '++*-', '+++/', '+++*', '++++', '+++-', '++-/', '++-*', '++-+', '++--', '+-//', '+-/*', '+-/+', '+-/-', '+-*/', '+-**', '+-*+', '+-*-', '+-+/', '+-+*', '+-++', '+-+-', '+--/', '+--*', '+--+', '+---', '-///', '-//*', '-//+', '-//-', '-/*/', '-/**', '-/*+', '-/*-', '-/+/', '-/+*', '-/++', '-/+-', '-/-/', '-/-*', '-/-+', '-/--', '-*//', '-*/*', '-*/+', '-*/-', '-**/', '-***', '-**+', '-**-', '-*+/', '-*+*', '-*++', '-*+-', '-*-/', '-*-*', '-*-+', '-*--', '-+//', '-+/*', '-+/+', '-+/-', '-+*/', '-+**', '-+*+', '-+*-', '-++/', '-++*', '-+++', '-++-', '-+-/', '-+-*', '-+-+', '-+--', '--//', '--/*', '--/+', '--/-', '--*/', '--**', '--*+', '--*-', '--+/', '--+*', '--++', '--+-', '---/', '---*', '---+', '----']
['///', '//*', '//+', '//-', '/*/', '/**', '/*+', '/*-', '/+/', '/+*', '/++', '/+-', '/-/', '/-*', '/-+', '/--', '*//', '*/*', '*/+', '*/-', '**/', '***', '**+', '**-', '*+/', '*+*', '*++', '*+-', '*-/', '*-*', '*-+', '*--', '+//', '+/*', '+/+', '+/-', '+*/', '+**', '+*+', '+*-', '++/', '++*', '+++', '++-', '+-/', '+-*', '+-+', '+--', '-//', '-/*', '-/+', '-/-', '-*/', '-**', '-*+', '-*-', '-+/', '-+*', '-++', '-+-', '--/', '--*', '--+', '---']

How can I do that?


Solution

  • Here's a generic solution for any value of 'repeat'.

    def pr(l, repeat=1):
        if repeat == 1:
            return [[x] for x in l]
        sub_prod = pr(l, repeat-1)
        return [ [x] + y for x in l for y in sub_prod ]
    
    o = ['/','*','+','-']
    
    pr(o, 3)
    

    Result:

    [['/', '/', '/'],
     ['/', '/', '*'],
     ['/', '/', '+'],
     ['/', '/', '-'],
     ['/', '*', '/'],
     ['/', '*', '*'],
     ['/', '*', '+'],
     ['/', '*', '-'],
     ['/', '+', '/'],
     ['/', '+', '*'],
     ['/', '+', '+'],
     ...
    

    If you want to turn each sublist to a string, use:

    ["".join(x) for x in pr(o, 3)]