Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
is there a reverse index?
#1
i need the index of the first occurrence of in s (at or after index i) just like s.index(x,i) but in reverse. that is, equivalent to testing slices of s[i:i+len(x)] for a decrementing value of i. anyone know of such a method or function? this is for a str type though a general solution for any sequence type would be great.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#2
str.rfind(sub_str, beginning, end)
Reply
#3
does it actually run across str in the reverse direction ... or does it run forward across all matches updating its result variable each time, returning it at the end?
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#4
(Jun-13-2019, 01:23 AM)Skaperen Wrote: does it actually run across str in the reverse direction ... or does it run forward across all matches updating its result variable each time, returning it at the end?
I cannot find documentation that conclusively confirms that it does or does not run backwards, I suppose you could examine the source code. You should be able to test it with an exceptionally long string that has only one instance of a specific key character. First, put the key character at the beginning of the string and time it. Then, put the key character at the end of the string and time it again.
Reply
#5
it turns out i need to do something odd in my find. i need to include a special code in the string i am looking for that will match a run of any number of white space characters much like str.split() with no arguments splits on. i think i need to make my own find function for this. i'm trying to think how str.split() might optimize this for me. for example if '_' is where the special code is and i am searching for 'foo_bar' then 'xfoo bary' will result in it being found at position 1 with an end of 10. the special code will need to be something extremely unlikely to ever be used or else i'll need to use lists an a non-character for it. i hope Unicode has something.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#6
https://github.com/python/cpython/blob/e...find.h#L26

Looks like it basically just calls FASTSEARCH with the FAST_RSEARCH param.

FASTSEARCH can be found here: https://github.com/python/cpython/blob/e...rch.h#L163

There's some setup, and then some special case testing (1-length strings, etc), then the RSEARCH part is here: https://github.com/python/cpython/blob/e...rch.h#L245

    } else {    /* FAST_RSEARCH */

        /* create compressed boyer-moore delta 1 table */

        /* process pattern[0] outside the loop */
        STRINGLIB_BLOOM_ADD(mask, p[0]);
        /* process pattern[:0:-1] */
        for (i = mlast; i > 0; i--) {
            STRINGLIB_BLOOM_ADD(mask, p[i]);
            if (p[i] == p[0])
                skip = i - 1;
        }

        for (i = w; i >= 0; i--) {
            if (s[i] == p[0]) {
                /* candidate match */
                for (j = mlast; j > 0; j--)
                    if (s[i+j] != p[j])
                        break;
                if (j == 0)
                    /* got a match! */
                    return i;
                /* miss: check if previous character is part of pattern */
                if (i > 0 && !STRINGLIB_BLOOM(mask, s[i-1]))
                    i = i - m;
                else
                    i = i - skip;
            } else {
                /* skip: check if previous character is part of pattern */
                if (i > 0 && !STRINGLIB_BLOOM(mask, s[i-1]))
                    i = i - m;
            }
        }
}
Without spending time studying that, I can't answer your question, but it kinda looks like it starts at the end of the string and crawls toward the front, stopping at the first match found.
Reply
#7
this seems to work when i get down to just comparing a string with the special code to the string with the run of white space:
    if look_for.split(special_code) == compare_to.split():
        ...
i have to be sure not to compare a shorter compare_to first since then it might have a truncated run of white space (this comparison would be equal for that case, too). if this comparison is true the length of compare_to needs to be known.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020