Reputation: 83
Working on a very common problem to identify whether word is abecedarian (all letters in alphabetical order). I can do one word in several ways as discovered in "Think Python"; but, would like to be able to iterate through a list of words determining which are abecedarian and counting those that are.
def start():
lines= []
words= []
for line in open('word_test1.txt'):
lines.append(line.strip())
numlines=len(lines)
count = 0
for word in lines[:]:
i = 0
while i < len(word)-1:
if word[i+1] < word[i]:
return
i = i+1
print (word)
count= count + 1
print (count)
start()
I think my problem lies with the "return" in the "while i" loop. In the list I'm using there are at least three abecedarian words. The above code reads the first two (which are the first entries), prints them, counts them but on the following non-abecedarian word breaks out of the loop and ends the program.
I'm new at programming and this has taken me several hours over a couple of days.
Upvotes: 4
Views: 2537
Reputation: 15
I have this solution for you - I have found it in the same place as you. I hope it still helps.
def is_abecedarian(word):
word.lower()
letter_value=0
for letter in word:
if ord(letter) < letter_value:
return False
else:
letter_value = ord(letter)
return True
fin = open('words.txt')
words_no = 0
for line in fin:
word = line.strip()
if is_abecedarian(word):
words_no = words_no + 1
print words_no
Upvotes: 0
Reputation: 10162
I like iterools:
from itertools import tee, izip
def pairwise(iterable):
a, b = tee(iterable)
next(b)
return izip(a, b)
def is_abcdarien(word):
return all(c < d for c, d in pairwise(word))
words = 'asdf', 'qwer', 'fghi', 'klmn', 'aabcd', 'abcd'
print filter(is_abcdarien, words)
print len(filter(is_abcdarien, words))
Result:
('fghi', 'klmn', 'abcd')
3
Change c < d
to c <= d
if you want non-strict ordering, so that "aabcd" is also abcdarian, .
Upvotes: 0
Reputation: 56654
A slightly reorganized approach:
def is_abcedarian(word):
return sorted(s)==list(s)
def main():
# read input file
with open('word_test1.txt') as inf:
words = [line.strip() for line in inf]
# figure out which words are "good"
good_words = [word for word in words if is_abcedarian(word)]
# print the "good" words
print("\n".join(good_words))
print(len(good_words))
if __name__=="__main__":
main()
Upvotes: 0
Reputation: 226376
No need for low level programming on this one :-)
def is_abcedarian(s):
'Determine whether the characters are in alphabetical order'
return list(s) == sorted(s)
The use filter to run over a list of words:
>>> filter(is_abcedarian, ['apple', 'bee', 'amp', 'sun'])
['bee', 'amp']
Upvotes: 11
Reputation: 63737
I believe you intended to break
from the while loop when you find the letter's are not in order and instead you issued the return
statement, which returns you from the function start
.
There could be couple of ways to do this
You can use Exception, to raise a StopIteration Exception and catch it outside the while loop.
for word in lines[:]:
try:
i = 0
while i < len(word)-1:
if word[i+1] < word[i]:
raise StopIteration
i = i+1
print (word)
except StopIteration:
None
You can also try setting a flag found
and then use it later to test for printing the word
Upvotes: 1
Reputation: 993343
The return
statement is breaking out of the entire start()
function. There are many possible ways to solve this, but the clearest might be to break your code into two functions like this:
def is_abcedarian(word):
i = 0
while i < len(word)-1:
if word[i+1] < word[i]:
return False
i = i+1
return True
def start():
lines= []
words= []
for line in open('word_test1.txt'):
lines.append(line.strip())
numlines=len(lines)
count = 0
for word in lines[:]:
if is_abcedearian(word):
print (word)
count= count + 1
print (count)
In this example, the return
statements in is_abcedarian()
returns only from that function, and the return value is then tested by the if
statement inside the for
loop.
Once you have split apart your program in this way, you have the added benefit of being able to use your is_abcedarian()
function from other places (in future related code you might write).
Upvotes: 3