0

My code isn't efficient, but it's not convoluted which is rare for me. I wrote a helper function, 'slicer', which iterates over the length of a and slices a into length n substrings. 'Substrings' calls 'slicer' makes a and b sets, uses .intersection to get the substrings in common, and then checks for any substrings less than length n and removes them, or that's the idea behind it. Because the substrings shorter than n are pulled out by an if statement, it didn't seem to matter if 'slicer' ran the entire length of a:

def slicer(a, n):
    """Slices string into substrings of length n"""

    # buffer for substrings
    buffer_subs = []

    # iterates over string
    for i in range(len(a)):

        # slices a into length n substrings and buffers them
        buffer_subs.append(a[i:n + i])

    return buffer_subs


def substrings(a, b, n):
    """Return substrings of length n in both a and b"""

    # calls slicer on string a and b
    a_sub = slicer(a, n)
    b_sub = slicer(b, n)

    # make a_sub and b_sub sets
    set_a_sub = set(a_sub)
    set_b_sub = set(b_sub)

    # combine sets a_sub and b_sub in list
    ab_sub = list(set_a_sub.intersection(set_b_sub))

    for s in ab_sub:
        if len(s) is not n:
            ab_sub.remove(s)

    return ab_sub

Check50 fails 3 cases:

check50 similarities(less)

The 'more detail' link is helpful...

check50 more detail

but I can only reproduce 2 of the 3 errors--1 substring in common looks ok to me:

enter image description here

It's returning substrings shorter than n, but I don't know if it's because the if statement is wrong, if slicer iterating thru the entire length of a is behind it (defining the range in terms of n makes the if statement unnecessary, but doesn't help me understand what's wrong), or if the overall approach is just bad. Maybe if the if statement were in slicer, but I don't understand why it would make a difference. This is where I really miss the gdb debugger. Thanks in advance for any help.

1 Answer 1

0

You could use for i in range(len(a) - n + 1): to avoid generating the extra words.

is tests for identity, while == tests for equality. Has funny consequences: (42 is 42.0) == False but (42 == 42.0) == True. In most cases, use == if you don't need is, that's more likely what you want.

And never change the iterable you're iterating over (like your "fix" does), this can have all kinds of effects. Most likely, removing current element will skip the next one. Stack Overflow question https://stackoverflow.com/questions/8544559/how-to-correctly-modify-the-iterator-of-a-loop-in-python-from-within-the-loop has a few answers how one could fix it. But I'd try avoiding the stuff instead, especially if it's that easy.

2
  • I came up with for i in range(len(a) - (n -1)) to represent the number of substrings of length n in a, and it seems to work out the same as yours. I didn't grasp the distinction btwn identity and equality--thanks so much for clarifying it. == looked strange with a string, but I should've tried it. Link is fabulous! So many code examples--they help so much.
    – Lindsey
    Commented Mar 27, 2018 at 16:37
  • Yes, you can even use < and others to sort strings. And the formula is the same.
    – Blauelf
    Commented Mar 27, 2018 at 17:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .