Sharuzzaman Ahmat Raslan
Sharuzzaman Ahmat Raslan

Reputation: 1657

Python: Create dynamic loop based on pattern

I'm still learning to code in Python

I want to generate a string based on pattern, the only way I know is by using for loop.

In example code below, I create a loop for "vcvcv" pattern. c=consonant, v=vowel

How to create a dynamic loop, based on pattern that I provide to the script?

eg. if pattern is "cvcvc" the loop should be build to produce the string

Help appeciated.

Thanks.

#!/bin/env python

vowel="aeiou"
consonant="bcdfghjklmnpqrstvwxyz"

lvowel=list(vowel)
lconsonant=list(consonant)

# pattern for "vcvcv" = ababa
for a in lvowel:
  for b in lconsonant:
    for c in lvowel:
      for d in lconsonant:
            for e in lvowel:
                  myname=a+b+c+d+e
                  print myname

# pattern for "cvcvc" = babab
# how to make the loop dynamic based on pattern ?

Upvotes: 0

Views: 603

Answers (3)

Arcturus
Arcturus

Reputation: 548

A somewhat more elaborate but easily customizable version for the first n permutations is given below,

def gen_pattern( seq, op = "" ):
      vowel="aeiou"
      consonant="bcdfghjklmnpqrstvwxyz"

      lvowel=list(vowel)
      lconsonant=list(consonant)
      if ( not seq ):
            print op
            return

      if ( seq[0] == 'v' ):
            for v in lvowel:
                  gen_pattern( seq[1:], op+v )
      elif ( seq[0] == 'c' ):
            for c in lconsonant:
                  gen_pattern( seq[1:],op+c )

if __name__ == "__main__":
      gen_pattern("vcvcv")

I agree it is more work though!

Upvotes: 0

user2089674
user2089674

Reputation: 2044

If you're just getting into programming and want to see a more general solution than the itertools one listed above, then recursion is your best bet, allowing you to arbitrarily nest loops.

There is a slight complication here, which you could use Python generators for, or else use simpler (but messier) constructs. An example of the latter is shown below.

Something like

def continuePattern(pat, strSoFar):
  if pat == '':
    print strSoFar
  elif pat[0] == 'v':
    for c in lvowel:
       continuePattern(pat[1:], strSoFar + c)
  elif pat[0] == 'c':
    for c in lconsonant:
       continuePattern(pat[1:], strSoFar + c)

This is one of several possible implementations, and one of the two most naive ones I can imagine.

Upvotes: 1

Blender
Blender

Reputation: 298582

Something like this should work:

import itertools

mapping = {
    'v': 'aeiou',
    'c': 'bcdfghjklmnpqrstvwxyz'
}

pattern = 'vcvcv'

for thing in itertools.product(*map(mapping.get, pattern)):
    print ''.join(thing)

Here's roughly how it works:

  • map(mapping.get, pattern) just converts 'vcv' to ['aeiou', 'bcdfghjklmnpqrstvwxyz', 'aeiou']. It replaces each letter with the corresponding list of characters.
  • *map(...) unpacks the argument list.
  • itertools.product() is like a bunch of nested for loops.
  • ''.join(thing) joins the list of characters into a single string.

If you want to do this without itertools, you'll have to make a recursive function.

Upvotes: 5

Related Questions