tags:

views:

86

answers:

5

Hi I was wondering if it was possible to assign a value in the while comparison section of the code.

Here is an example of the code currently

startIndex = find(target, key, startIndex)
while( startIndex != -1):
    matchesFound += 1
    startIndex = find(target, key, startIndex + 1)
return matchesFound

What I want to do is move the startIndex = find(target, key, startIndex) into the while comparison expresion so it would look something like this

while( (startIndex = find(target, key, startIndex)) != -1):
    matchesFound += 1
    startIndex + 1
return matchesFound

if not, what would a better refactor be?

Thanks

edit I'm working through the MIT Open courseware 6.00 before I try out the famous 6.001 module

A: 

No, you can't do that in Python. I think the main reason Python disallows this, is to avoid the frequent errors resulting from confusing assignment and equality checking.

Python claims to have readable code as a main guideline, so I think your original code is fine. No need to refactor...

3lectrologos
+1  A: 

You're writing C in Python.

Try:

startIndex = -1
while True:
    startIndex = find(target, key, startIndex + 1)
    if startIndex < 0:
        break
    matchesFound += 1
return matchesFound

Or perhaps even:

return target.count(key)
retracile
This doesn't match the OP's code. `startIndex` needs to be incremented by 1 on calls after the first one, apparently.
Peter Hansen
+1 for recognizing as a C convention...though I'm sure it's legal in other languages.
AJ
I actually did a 14 month placement were I was programming in C too
Sam
@Peter: good catch; fixed.
retracile
You need the +1 outside of the parens, take a look at my answer.
Roger Pate
@Roger: They are equivalent.
retracile
No, the first iteration you pass 1 (0 + 1) as find's 3rd parameter, where I pass 0.
Roger Pate
@Roger: *doh* You are correct, sir. Thanks for pointing that out again. (Ok, fixed to pass 0 (-1 + 1) on the first iteration.)
retracile
A: 

i would do it like this

startIndex=0
while 1:
    startIndex = find(target, key, startIndex+1)
    if startIndex == -1: break
    matchesFound += 1

you can put in more conditions inside the while loop like that.

Edit: @OP, in future, to count match of string, just use count

>>> mystring = "abc defabc fgh ijkabc blah"
>>> mystring.count("abc")
3
>>>
ghostdog74
Also apparently doesn't match the OP's code, where `startIndex` is passed in advanced by 1 on calls after the first.
Peter Hansen
A: 

Edit.

We refactor it like this.

matches = [ k for k in range(len(target)-len(key)) if target[k:].startswith(key) ]
matchesFound = len(matches)

We don't need C-style condition and assignment conflation.

Rarely do you simply want the count; the actual locations are available for free.

S.Lott
+2  A: 

If for some reason you can't use a more appropriate method from whatever you're searching, this is equivalent to your working code from the question:

start = 0
count = 0
for match in iter(lambda: find(target, key, start), -1):
  count += 1
  start = match + 1
return count

However, you'll get the most mileage out of writing an iterator for finding these matches, "transforming" your current find function:

def findall(target, key, start=0):
  for match in iter(lambda: find(target, key, start), -1):
    yield match
    start = match + 1

Then count from that:

count = sum(1 for m in findall(target, key))
Roger Pate
+1 for first that's both Pythonic *and* (more importantly) actually matches the OP's first example in behaviour.
Peter Hansen
I'm not sure about more pythonic, the loop-and-a-half is a good candidate, but the question appears to be just example code and this form of iter() might work better in what he's really doing. :) (I also made the assumption startIndex starts at 0 which wasn't stated, though obviously that's easy enough to change.)
Roger Pate
I'm doing the assignments in the MIT 6.00 course, this assignment was just write two functions(one iterativly and one recursivly) to count how many times a key string appeared in the target string
Sam
Let's say "elegant" rather than merely "Pythonic" since, as you say, even the loop-and-a-half is definitely Pythonic. Even were it not, I'd still give you the +1 for nice use of the sentinel argument! :)
Peter Hansen