What causes `.find()` to return -1?

I have a question for comprehending the behaviour of this method:

I needed to distinguish elements of a list through checking if they have a specific character in them. I used the following code to test the behaviour of ‘.find’

test2 = []  
test = ['white', 'black&white', 'greenayellow&blue']
for i in test:

  test2.append(i.find('&'))

print(test2)

this gave me the list

[-1, 5, 12]

I mean, this is really useful for checking what I want, but I don’t understand why ‘.find’ returns “-1” if the searched for string is not in the element.

Any pointers?

its common, in JS you have something similar.

i assume the logic is you want to return an integer (so you only have a single return type), 0 can’t be, given the first character might be a match, which would be at index zero. So then -1 is the most logic value

2 Likes

Does there need to be a reason, is there something that makes this particularly strange? Seems like you’re having a thought here that changes the meaning of the question, or maybe finishing the thought even answers it.

There are other ways to deal with the possibly missing result.

I should also point out that find and similar functions are rarely the most suitable tool available. Usually you’re only interested in yes/no, or if you do want the locations, then you usually want many locations, and then you would make a lookup table instead of repeatedly searching through the data over and over again.

Here for example, two groups are made based on whether or not there’s an '&' in it. The location isn’t interesting.

> things = ["white", "black&white", "greenayellow&blue"]
> things & partition (any (== '&'))
(["black&white","greenayellow&blue"],["white"])

Or maybe one would split them all on & and join it with the single values:

> things <&> splitOn "&" & concat
["white","black","white","greenayellow","blue"]

Where were the &'s? Don’t care.

1 Like

The problem was trying to work the problem with the methods I had learned until then. I know that there are more powerful ways to get the functionality I want, but these were the ones I knew.

I don’t recognise the synthax in your example. Is this still python or another language entirely?

Python? No. But you can still see what the involved parts are so long as I don’t put too many things into it.

Take some things, partition on whether any element is equal to ‘&’
Take some things, split them on ‘&’, flatten the results (concat)

The operation you’d want here is one exposed by python’s in operator. What exactly it does depends on the type of value you’re using it with, but generally means “contains” or “has”, so

pairs = [color for color in colors if '&' in color]
singles = [color for color in colors if '&' not in color]

python, this time.

1 Like

Thank you! I am still struggling to wrap my head around list comprehension. Somehow I find it hard to follow what the loop does exactly or how to get it working for some cases I came across.

The expression on the left is the value to keep.
You can have multiple for and if parts. For multiple if’s all have to be met, for multiple for’s, that works just like nesting for-loops.

# some coordinates for a grid.
# skipping (1, 1) because.. ... just so I can have an if
# could remove the if too. or put in some more.
# could put an if between the for's too.
[(x, y)
 for x in range(10)
 for y in range(5)
 if (x, y) != (1, 1)
]
2 Likes

Again, thank you. Your example using list comprehension really helped me out with the code challenge “Count Letters” I am doing right now. Somehow the example you used made it so much clearer for me!

Hey, I also got a -1 at first and I think I figured out why…

1 Like

Thanks for posting this - I was confused reading through this thread, but your example is the one that made sense to me immediately!

-1 is a logic code for “False”.