7
\$\begingroup\$

I'm trying to write code in the simplest and cleanest way possible. I've found a few ways to shorten and simplify my code through functions that I've never seen before or through using other methods. I'd like to expand my knowledge on writing code using various (but simple) methods, and also expand my function 'vocabulary'.

What I mainly want to know is if there are other ways of writing the for loop such that it is much easier to read, and is shorter and simpler. Just yesterday I found out that the enumerate function exists, which made my life so much easier! :)

On to the question-

Substring Counter: (I thought of this function as a programming challenge for myself)

A function that takes in a string and returns the amount of times 'A' ends with 'Z'. MUST ONLY CONTAIN 1 LOOP. Not sure how to explain these, but here are examples: substring_counter(string) It is assumed that the input is a string and that all characters are alphabetical and capital. I know I can put checks for all these but I'm mainly focusing on the logical way the code is written.

substring_counter('AZAAZ')
> 4

'AZAAZ' has 4 instances where it starts with 'A' and ends with 'Z'.

'AZAAZ'

'AZAAZ'

'AZAAZ'

'AZAAZ'

substring_counter('AZZ')
> 2

'AZZ' has 2 instances where it starts with 'A' and ends with 'Z'.

'AZZ' 'AZZ'

1st method (using slicing):

def substring_counter(string):
    counter = 0
    for num, x in enumerate(string):
        if x == 'A':
            if  string[num:].find('Z') != -1:
                counter += string[num:].count('Z')
    return counter

2nd method (using counters):

def substring_counter(x):
    counter=0
    word = 0
    for i in x:
        if(i == 'A'):
           word += 1
        elif(i == 'Z'): 
           counter += word
    return counter

Which method is more understandable, or simpler? Which one should I be using?

\$\endgroup\$
3
\$\begingroup\$

The second solution seems to be clearer and more efficient. In both cases, a few details can be improved:

  • variable names
  • removing useless whitespaces
  • removing useless parenthesis
  • removing useless tests (no need to call find before calling count)
  • using the start parameter of count (suggestion of @SolomonUcko).

You'd get something like:

def substring_counter(string):
    counter = 0
    for num, c in enumerate(string):
        if c == 'A':
            counter += string.count('Z', num)
    return counter

def substring_counter2(string):
    counter = 0
    nb_a = 0
    for c in string:
        if c == 'A':
           nb_a += 1
        elif c == 'Z':
           counter += nb_a
    return counter
\$\endgroup\$
  • 1
    \$\begingroup\$ Can you use string.count('Z', num) instead of string[num:].count('Z')? \$\endgroup\$ – Solomon Ucko Apr 2 '18 at 20:54
  • \$\begingroup\$ @SolomonUcko Excellent suggestion! I've edited my answer :-) \$\endgroup\$ – SylvainD Apr 2 '18 at 21:09
  • \$\begingroup\$ Also, I think num_a would make more sense then nb_a, and count would make more sense then counter. \$\endgroup\$ – Solomon Ucko Apr 2 '18 at 22:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.