Sequences in list

Michael Spencer mahs at telcopartners.com
Tue May 3 16:12:46 EDT 2005


temp at mclift.fsnet.co.uk wrote:
> Hi Michael,
> 
> Thanks for a quick response, I appreciate it. I will have to get back
> to you tomorrow, as I can't check what you've given me right now. I
> presume the fact that you mention the word note in your code you have
> realised that I'm trying to search for musical sequences. 

Yes, I thought that was the most likely application

I tried to
> put my problem across in the way I did, not mentioning music, so as not
> to confuse the matter. So simply put, I'm checking a list for musical
> sequences, without having any idea as to how they might be formed.
> 

What I put together does not yet address the general problem.  In particular, it 
looks only at groups that start at positions that are an integral multiple of 
their length i.e., 3-tuples starting only at 0,3,6,9...  If you really want to 
look for repetition of any sequence anywhere, then you would need a small 
modification to the make_groups function:

def make_groups(sequence, n, anywhere = False):
     """return groups of length n from sequence.

     bool: anywhere
       False: look only at positions n*i for i = 1,2,3...
       True: return every (overlapping sequence) of length n

     Usage:
      >>> list(make_groups(s1,3))
     [['a', 'b', 'c'], ['b', 'c', 'd'], ['c', 'd', 'e']]
      >>> list(make_groups(s1,3,anywhere = True))
      [['a', 'b', 'c'], ['b', 'c', 'b'], ['c', 'b', 'c'], ['b', 'c', 'd'],
      ['c', 'd', 'c'], ['d', 'c', 'd'], ['c', 'd', 'e']]
      >>>
     """
     length = len(sequence)
     if (length % n) and not anywhere:
         raise ValueError, "Sequence length %s is not multiple of %s"\
                             % (length, n)
     for i in xrange(0, length-n+1, anywhere or n):
         yield sequence[i:i+n]

and a corresponding tweak to the compare_forms:

def compare_forms(sequence, anywhere = False):
     """test whether all groups of a sequence have the same form"""
     for length in (4,3,2): # look for longest match first
         forms = {}
         try:
             for group in make_diffs(make_groups(sequence, length, anywhere)):
                 forms[group] = forms.get(group,0)+1
             print forms
         except ValueError:
             # raised if the sequence is not a multiple of length
             pass

  >>> compare_forms(s1, anywhere = True)
  {(0, 6, 0, 1): 2, (0, 1, 2, 1): 2, (0, 1, 0, 1): 2}
  {(0, 1, 2): 3, (0, 1, 0): 2, (0, 6, 0): 2}
  {(0, 1): 6, (0, 6): 2}
  >>>


Other questions - are your search sequences really limited to 4 notes?  How long 
are the pieces you are searching?  Do you not need to care about note lengths, 
only pitches.  Are you really (as I inferred from your examples) looking only at 
a 7-tone scale etc... etc...  Anyway, I'd be happy to discuss this on-list or off.

Michael






More information about the Python-list mailing list