2

I'd like to find the location in a string for certain characters such as "FC" or "FL". For single case like FC, I used the find() function to return the index of the characters in a string, as below.

for line in myfile:
    location = line.find('FC')

But when it comes to adding FL, how do I add it without using an if statement in the for loop? I don't want to add redundant lines so I hope there is an elegant solution.

Each line will include either "FC" or "FL" but not both.

4 Answers 4

3

Each line will include either "FC" or "FL" but not both.

That makes the following somewhat hacky trick possible:

location = max(line.find(sub) for sub in ("FC", "FL"))

The idea is that of the two values, one will be -1 and the other will be positive (the index where it was found) so the greater value is the location.

Note that if "FC" is found the method will still search for "FL" and not find it, which will reduce performance if the string being searched is long, whereas solutions using a conditional will avoid this redundant calculation. However if the string is short then using the least amount of python code and letting C do all the thinking is probably fastest (though you should test your case if it really matters).

You can also avoid using a for comprehension for this simple function call:

location = max(map(line.find, ("FC", "FL")))
Sign up to request clarification or add additional context in comments.

1 Comment

That's probably the most elegant solution suggested!
1

You can do this:

for line in myfile:
    location = [line.find(substring) for substring in ('FC', 'FL') if line.find(substring) != -1][0]

It's similar to the solution suggested by @NathanielFord, the only difference is, I added if line.find(substring) != -1 to the generator to solve the problem I pointed at and moved getting the element with zero index to the same line to make it shorter. (@NathanielFord, I'm sorry you removed your answer before I suggested this in the comments)

Though, it's not a very elegant solution because it will call .find() twice, but it is shorter than using fors.

1 Comment

No worries! This is a good solution. I forgot that you can use if in the for comprehension.
1

If you want the most elegant solution, then a conditional is probably your solution. It won't be a "redundant" line, but it will make your code look nice and readable:

for line in myfile:
    location = line.find('FC')
    if location == -1:
        location = line.find('FL')

3 Comments

The problem is, str.find returns -1 if substring is not found, therefore location will always be just True, so it won't solve the problem.
I tested it with sample line"1234FCHdggf" and "1234FLHdggf" but it only returns correct location for first but it returns -1 for the latter. why is that?
@JoohunLee Yep, my bad. I forgot it returns -1 and not None
0

It is a little unclear what your desired output is, and there are more elegant ways to handle it depending on that, but essentially you're looking for:

def multifind(line):
    for substring in ['FC', 'FL']:
        location = line.find(substring)
        if location is not -1:
            return location
    return None

locations = [multifind(line) for line in myfile]

Sample run:

myfile = ["abcFCabc","abFLcabc", "abc", ""]
>>> def multifind(line):
...     for substring in ['FC', 'FL']:
...         location = line.find(substring)
...         if location is not -1:
...             return location
...     return None
... 
>>> locations = [multifind(line) for line in myfile]
>>> locations
[3, 2, None, None]

Note that this is not quite as elegant as the solution with the if inside the for loop.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.