I am trying to create a program that asks the user for three words and prints 'True' if the words are entered in dictionary order. E.G:
Enter first word: chicken
Enter second word: fish
Enter third word: zebra
True
Here is my code so far:
first = (input('Enter first word: '))
second = (input('Enter second word: '))
third = (input('Enter third word: '))
s = ['a','b','c','d','e','f','g','h',
'i','j','k','l','m','n','o','p',
'q','r','s','t','u','v','w','x',
'y','z','A','B','C','D','E','F',
'G','H','I','J','K','L','M','N',
'O','P','Q','R','S','T','U','V',
'W','Z','Y','Z']
if s.find(first[0]) > s.find(second[0]) and s.find(second[0]) > s.find(third[0]):
print(True)
If you work on a list of arbitrary length, I believe using sorted()
as other answers indicate is good for small lists (with small strings) , when it comes to larger lists and larger strings and cases (and cases where the list can be randomly ordered), a faster way would be to use all()
built-in function and a generator expression (This should be faster than the sorted()
approach). Example -
#Assuming list is called lst
print(all(lst[i].lower() < lst[i+1].lower() for i in range(len(lst)-1)))
Please note, above would end up calling str.lower()
on every string (except for first and last) twice. Unless your strings are very large, this should be fine.
If your strings are really very large compared to the length of the list, you can create another temporary list before doing the all()
that stores all the strings in lowercase. And then run same logic on that list.
You can create your list (by taking inputs from the user) using a list comprehension, Example -
lst = [input("Enter word {}:".format(i)) for i in range(3)] #Change 3 to the number of elements you want to take input from user.
Timing results of the above method vs sorted()
(modified code of sorted()
to work case-insensitively) -
In [5]: lst = ['{:0>7}'.format(i) for i in range(1000000)]
In [6]: lst == sorted(lst,key=str.lower)
Out[6]: True
In [7]: %timeit lst == sorted(lst,key=str.lower)
1 loops, best of 3: 204 ms per loop
In [8]: %timeit all(lst[i].lower() < lst[i+1].lower() for i in range(len(lst)-1))
1 loops, best of 3: 439 ms per loop
In [11]: lst = ['{:0>7}'.format(random.randint(1,10000)) for i in range(1000000)]
In [12]: %timeit lst == sorted(lst,key=str.lower)
1 loops, best of 3: 1.08 s per loop
In [13]: %timeit all(lst[i].lower() < lst[i+1].lower() for i in range(len(lst)-1))
The slowest run took 6.20 times longer than the fastest. This could mean that an intermediate result is being cached
100000 loops, best of 3: 2.89 µs per loop
Result -
For cases that should return True
(that is already sorted lists) the using sorted()
is quite faster than all()
, since sorted()
works well for mostly-sorted lists.
For cases that are random, all()
works better than sorted()
because of the short-circuiting nature of the all()
(it would short-circuit when it sees the first False
).
Also, there is the fact that sorted()
would create a temporary (sorted list) in memory (for comparison), whereas all()
would not require that (and this fact does attribute to the timings we see above).
Earlier answer that directly (and only applies to this question) you can simply directly compare the strings as such, you do not need another string/list for alphabets. Example -
first = (input('Enter first word: '))
second = (input('Enter second word: '))
third = (input('Enter third word: '))
if first <= second <= third:
print(True)
Or if you want to compare only the first characters (though I highly doubt that) -
if first[0] <= second[0] <= third[0]:
print(True)
To compare the strings case-insensitively, you can convert all the string to lowercase, before comparison. Example -
if first.lower() <= second.lower() <= third.lower():
print(True)
Or the simpler -
print(first.lower() <= second.lower() <= third.lower())
Yes, lists do not have the find
method. Though you don't even have to use lists. The <=
(as well as >=
) operator compare sequences lexicographically. In addition, Python supports chained comparisons. Here's how I'd write it:
first = input('Enter first word: ')
second = input('Enter second word: ')
third = input('Enter third word: ')
print(first <= second <= third)
If there're more than 3 words, you'd gather them into a list, sort it and compare it against the source list. Example:
words = input('Enter words (separated by whitespace): ').split()
print(sorted(words) == words) # True if sorted() didn't re-order anything
Both of these approaches will work reasonably well for small number of words. If the number of words is big, you should consider using a short-circuiting solution using the built-in all
function and a generator expression:
prev_it, cur_it = iter(words), iter(words)
# Consume first element
next(cur_it)
# Pairwise iteration
print(all(prev <= cur for prev, cur in zip(prev_it, cur_it)))
which is an efficient generalization of the first solution.
If you want to perform case-insensitive comparison, use str.lower
(or str.casefold
, in Python 3.3+).
Example for the first code snippet:
print(first.lower() <= second.lower() <= third.lower())
Example for the list-based approaches:
words = [s.lower() for s in input('Enter words (separated by whitespace): ').split()]
Store the words in a list
and then check it with sorted()
. You can make it ignore case by specifying a key that looks at the lowercase version of each word for comparison:
words = input("Enter three words, separated by spaces: ").split()
print(words == sorted(words, key=str.lower))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With