list index()

B

Ben Finney

Thorsten Kampe said:
* Ben Finney (Thu, 30 Aug 2007 18:02:15 +1000)
Now now, no need for snappiness.

Actually there was. The OP's claim [...] ...is just plain nonsense.

Which was pointed out in several ways without snapping. Hence the part
of my response you omitted.

Ben said:
If you don't feel a constructive response is merited, please ignore.

There's no need to fuel flames with content-free flaming, and Bruno
agreed with that when it was pointed out. If one doesn't have the time
or inclination to post a constructive response, not responding at all
is better than flaming.

The Python community is remarkable for its low level of flaming and
high level of content in this forum, even in response to poor
attitudes and cluelessness. I'd like it to remain that way.
 
T

TheFlyingDutchman

Actually there was. The OP's claim
| There are a million situations where you can have an item not be in
| a list and it is not an exception situation.

...is just plain nonsense. zzbbaadd neither does understand exceptions
nor what they are used for in Python. An item not being in a list is
an exception situation /by definition/.

It won't be /by definition/ in my fork of Python 3, which I am pleased
to announce now, is called Python 3.01 while in development, and will
be known as Python 3000 or Python 3K when it gets to a productional
release. So in regard to Python 3000, your statement will be plain
nonsense.
 
C

Carsten Haese

[...] my fork of Python 3, which I am
pleased to announce now, is called Python 3.01 while in development,
and will be known as Python 3000 or Python 3K when it gets to a productional
release.

I hope you're joking.

-Carsten
 
J

Jason

What about -1? C programmers do this all the time. :)

Ciao,
Marc 'BlackJack' Rintsch

As other people pointed out, C doesn't have exceptions, so a C
programmer must make an in/out parameter to indicate an error, or have
a special return value. In Python, you're most often searching the
list for an object which is in the list, so the lack of the object is
an exceptional condition. You can certain check with the "in"
operator beforehand to avoid the exception. You may also subclass a
list and override the index method, or write a standalone function to
catch the exception and change its value.

The reason why the exception is more Pythonic is that the return value
is always a guaranteed good index into the list. Any errors
(including calling .index() on a non-list instance that doesn't have
a .index method) are exceptional, and should probably follow a very
different code path.

Returning -1 is not a good return value to indicate an error. After
all, -1 is a valid index in most Python lists. (Negative numbers
index from the tail of the list.)

--Jason
 
C

Campbell Barton

Jason said:
As other people pointed out, C doesn't have exceptions, so a C
programmer must make an in/out parameter to indicate an error, or have
a special return value. In Python, you're most often searching the
list for an object which is in the list, so the lack of the object is
an exceptional condition. You can certain check with the "in"
operator beforehand to avoid the exception. You may also subclass a
list and override the index method, or write a standalone function to
catch the exception and change its value.

The reason why the exception is more Pythonic is that the return value
is always a guaranteed good index into the list. Any errors
(including calling .index() on a non-list instance that doesn't have
a .index method) are exceptional, and should probably follow a very
different code path.

Returning -1 is not a good return value to indicate an error. After
all, -1 is a valid index in most Python lists. (Negative numbers
index from the tail of the list.)

--Jason

Agree in general tho its a bit inconsistent how...

"string".find(val)

....can return -1 but .index() cant, though the inconsistency is probably
with string since most other areas of the py api raise errors in cases
like this.
 
N

Neil Cerutti

Tim said:
Erik Max Francis wrote:
Paddy wrote:
I say the 'oll' in troll like the 'ol' in frolic, and pronounce roll
and role similarly.
My accent is probably from the East Midlands of the UK, but is not
pronounced.
_Troll_ and _frolic_ aren't pronounced with the same "o" sound in any
accent I've ever heard of. Which you pronounce _boat_ and _bot_ the
same way, too?
[Amusingly contemplating a trolling war about the pronunciation of "troll"]
Well they sound the same in my more-or-less South London accent.
I can't write those funny phonetic symbols (and I hate to
imagine the Unicode encoding hoops I'd have to jump through
to make them readable anyway) but both "o"s sound short to me.
Like "bot" rather than "boat" using your example.

Since we're talking... I'm still a little startled when I listen
to some of the excellent webcasts that are being produced these
days (showmedo.com and friends) and hear American voices pronounce
Python... well, the way they do, with the stress and something of a
drawl on the second syllable. I'm sure it's just as amusing the other
way round: we pronounce it with the stress on the first syllable and
the characteristic short vowel sound in the second.
(Something like: Pie'thun).

TJG

The only true way of pronouncing Python (the computing language), is
the way it is done at the beginning of Monty Pythons Flying Circus of
course :)

Your right, the American way does make me pause.

Ya'll can keep yer gall-dern schwa outta my Pie-thawn, ya hear?
 
N

Neil Cerutti

Agree in general tho its a bit inconsistent how...

"string".find(val)

...can return -1 but .index() cant, though the inconsistency is
probably with string since most other areas of the py api raise
errors in cases like this.

The two functions have different ranges, but also different
domains.

sequence.index
domain: any item '==' to an item in sequence
range: All non-negative indexes of sequence

string.find
domain: any string
range: -1 for not found, and all non-negative indexes of string.

If you want to search for subsequences in a sequence, a la
string.find, you can use something like (what I naively assume
will be a maximally efficent):

def find(seq, subseq):
""" Find a subsequence of seq in seq, and return its index. Return -1 if
subseq is not found.
>>> seq = [0, 1, 2, 3, 4, 5]
>>> find(seq, [0, 1, 2]) 0
>>> find(seq, []) 0
>>> find(seq, [3, 4]) 3
>>> find(seq, [3, 2]) -1
>>> find(seq, [5, 6]) -1
>>> find(seq, [3]) 3
>>> find(seq, [0, 2])
-1

"""
i = 0
j = 0
while i < len(seq) and j < len(subseq):
if seq == subseq[j]:
j += 1
else:
j = 0
i += 1
if j == len(subseq): return i - j
else: return -1

It's probable that a simpler implementation using slice
operations will be faster for shortish lengths of subseq. It was
certainly easier to get it working correctly. ;)

def find(seq, subseq):
for i, j in itertools.izip(xrange(len(seq)-len(subseq)),
xrange(len(subseq), len(seq))):
if subseq == seq[i:j]:
return i
return -1
 
L

Lawrence D'Oliveiro

Jason said:
The reason why the exception is more Pythonic is that the return value
is always a guaranteed good index into the list.

How do you explain dict.get, then?
 
B

Ben Finney

Lawrence D'Oliveiro said:
How do you explain dict.get, then?

I explain it by noting that list.index and dict.get serve totally
different purposes. The former returns the index given a value; the
latter returns a value given a key.

There are many areas of poor symmetry in the language and libraries;
it isn't particularly clever or difficult to find them if one
looks. Doing so doesn't appear to illustrate any point I see relevant
in this thread.
 
A

Alex Martelli

Neil Cerutti said:
It's probable that a simpler implementation using slice
operations will be faster for shortish lengths of subseq. It was
certainly easier to get it working correctly. ;)

def find(seq, subseq):
for i, j in itertools.izip(xrange(len(seq)-len(subseq)),
xrange(len(subseq), len(seq))):
if subseq == seq[i:j]:
return i
return -1

Simpler yet (though maybe slower!-):

def find(seq, subseq):
L = len(subseq)
for i in xrange(0, len(seq)-L):
if subseq == seq[i:i+L]: return i
return -1

also worth trying (may be faster in some cases, e.g. when the first item
of the subsequence occurs rarely in the sequence):

def find(seq, subseq):
L = len(subseq)
firstitem = subseq[0]
end = len(seq) - len(subseq)
i = -1
while 1:
try: i = seq.index(firstitem, i+1, end)
except ValueError: return -1
if subseq == seq[i:i+L]: return i

For particularly long sequences (with hashable items) it might even be
worth trying variants of Boyer-Moore, Horspool, or Knuth-Morris-Pratt;
while these search algorithms are mostly intended for text strings,
since you need tables indexed by the item values, using dicts for such
tables might yet be feasible (however, the program won't be quite that
simple). Benchmarking of various possibilities on typical input data
for your application is recommended, as performance may vary!


Alex
 
T

TheFlyingDutchman

I explain it by noting that list.index and dict.get serve totally
different purposes. The former returns the index given a value; the
latter returns a value given a key.

And the former raises an exception if the value is not found, while
the latter returns None if the value is not found.
There are many areas of poor symmetry in the language and libraries;
it isn't particularly clever or difficult to find them if one
looks. Doing so doesn't appear to illustrate any point I see relevant
in this thread.

It has been stated in this thread, that in Python, exceptions are used
differently than in other languages. Rather than just use them for
catastrophic errors that can't be dealt with, Python raises exceptions
on routine and survivable situations such as an item not found in a
list. It was mentioned that an exception is more Pythonic than
returning a "not found" value.

Someone pointed out that find() in str was a contradiction to this
since it doesn't throw an exception but returns a "not found" value,
and the response was that it was believed that find() would be removed
from the language (if so, it does not currently show up on the
"removed list" as has_key() and a few others do -
http://docs.python.org/dev/3.0/whatsnew/3.0.html) and was only there
for "historical reasons".

I don't believe the poster was trying to illustrate a point already
mentioned in the thread, but to give a contradiction to statements in
the thread. He was asking the question - why doesn't dict.get() throw
an exception on not found if that is the Pythonic way?
 
S

Steve Holden

TheFlyingDutchman said:
And the former raises an exception if the value is not found, while
the latter returns None if the value is not found.


It has been stated in this thread, that in Python, exceptions are used
differently than in other languages. Rather than just use them for
catastrophic errors that can't be dealt with, Python raises exceptions
on routine and survivable situations such as an item not found in a
list. It was mentioned that an exception is more Pythonic than
returning a "not found" value.

Someone pointed out that find() in str was a contradiction to this
since it doesn't throw an exception but returns a "not found" value,
and the response was that it was believed that find() would be removed
from the language (if so, it does not currently show up on the
"removed list" as has_key() and a few others do -
http://docs.python.org/dev/3.0/whatsnew/3.0.html) and was only there
for "historical reasons".

I don't believe the poster was trying to illustrate a point already
mentioned in the thread, but to give a contradiction to statements in
the thread. He was asking the question - why doesn't dict.get() throw
an exception on not found if that is the Pythonic way?
Because it's an explicit short-cut for a frequently-required paradigm.
It's effectively an extension to dict indexing - which, you will recall,
*does* raise an exception when the key is not found. Does *everything*
have to raise such an exception?

There's no requirement for Python to be 100% consistent in its
application of a principle, but on the whole it is reasonably consistent.

For Pete's sake stop wasting your time and go do some programming.
Nothing will ever be perfect, not even Python ;-)

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://del.icio.us/steve.holden
--------------- Asciimercial ------------------
Get on the web: Blog, lens and tag the Internet
Many services currently offer free registration
----------- Thank You for Reading -------------
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top