views:

176

answers:

3

I was trying to write an answer to this question and was quite surprised to find out that there is no find method for lists, lists have only the index method (strings have find and index).

Can anyone tell me the rationale behind that? Why strings have both?

+4  A: 

I don't know why or maybe is buried in some PEP somewhere, but i do know 2 very basic "find" method for lists, and they are array.index() and the in operator. You can always make use of these 2 to find your items. (Also, re module, etc)

ghostdog74
`index` method and `in` operator can look for single items in lists (Somebody please tell me if I can call them atomic). OP wants to know if he can find whether a list is a sub-list of another with items appearing in the same order.
dheerosaur
But the basic principle behind is also iteration through the list, whether its nested or not, and finding them with these operators. OP is also free to develop own method/classes/generators etc for that.
ghostdog74
The standard `find` method for arrays is to search for a single item. Nobody would be surprised to learn that an array implementation doesn't do substring searches.
Glenn Maynard
@Glenn Maynard: With Python's otherwise very thorough treatment of lists, and its insistence on strings being treated similar to lists, I do find it surprising.
Tim Yates
+1  A: 

The "find" method for lists is index.

I do consider the inconsistency between string.find and list.index to be unfortunate, both in name and behavior: string.find returns -1 when no match is found, where list.index raises ValueError. This could have been designed more consistently. The only irreconcilable difference between these operations is that string.find searches for a string of items, where list.index searches for exactly one item (which, alone, doesn't justify using different names).

Glenn Maynard
try `"asdfasdf".index('z')` next time your in an REPL.
aaronasterling
@AaronMcSmooth: It highlights the absurdity of the oft-parroted "one obvious way to do something", when they can't even hold to it for core string methods.
Glenn Maynard
but the point of my example is that they _do_ hold to it. `list` and `string` both have an `index` method that behaves exactly the same. it's just that `string` adds a `find` method on top of that. I'm not sure why they don't do it for `list` as well but there is no equivalence between `list.index` and `string.find`.
aaronasterling
@AaronMcSmooth: The inconsistency is just shifted a little, with the underlying cause being the redundant search functions. (`getattr` handles this properly, allowing both a sentinel or an exception depending on what's needed.)
Glenn Maynard
@AaronMcSmooth, although `string` and `list` both have an `.index()` method, it doesn't do quite the same thing. For strings it will find substring, but a sublist of a list -- which to me is another example of the inconsistency.
martineau
@marineau, that's a great point. I suppose I'm wrong. not the first time by a mile
aaronasterling
@AaronMcSmooth. How can you see and respond to my comment before I even hit the 'Add Comment' button? It really throws me off and now I can't fix the typos in it.
martineau
+1  A: 

Why would you need find if you have index? I think lists do not have find because technically find returns the first index of a substring. If you applied that notion to lists you would be able to say something like:

>[1,2,3,4,5].find([3,4])
2
># or
>["hello","world"].find("rld")
1

This is pretty counter intuitive for lists and doesn't seem very pythonic. There is list comprehension for accomplishing this sort of thing.

Gabriel
why lists have both?