Reputation: 1794
A homework assignment asks us to write some functions, namely orSearch
and andSearch
.
"""
Input: an inverse index, as created by makeInverseIndex, and a list of words to query
Output: the set of document ids that contain _any_ of the specified words
Feel free to use a loop instead of a comprehension.
>>> idx = makeInverseIndex(['Johann Sebastian Bach', 'Johannes Brahms', 'Johann Strauss the Younger', 'Johann Strauss the Elder', ' Johann Christian Bach', 'Carl Philipp Emanuel Bach'])
>>> orSearch(idx, ['Bach','the'])
{0, 2, 3, 4, 5}
>>> orSearch(idx, ['Johann', 'Carl'])
{0, 2, 3, 4, 5}
"""
Given above is the documentation of orSearch
similarly in andSearch
we return only those set of docs which contains all instances of the query list.
We can assume that the inverse index has already been provided. An example of an inverse index for ['hello world','hello','hello cat','hellolot of cats']
is {'hello': {0, 1, 2}, 'cat': {2}, 'of': {3}, 'world': {0}, 'cats': {3}, 'hellolot': {3}}
So my question is, I was able to write a single line comprehension for the orSearch
method given by
def orSearch(inverseIndex, query):
return {index for word in query if word in inverseIndex.keys() for index in inverseIndex[word]}
But I am unable to think of the most pythonic way of writing andSearch
. I have written the following code, it works but I guess it is not that pythonic
def andSearch(inverseIndex, query):
if len(query) != 0:
result = inverseIndex[query[0]]
else:
result = set()
for word in query:
if word in inverseIndex.keys():
result = result & inverseIndex[word]
return result
Any suggestions on more compact code for andSearch
?
Upvotes: 0
Views: 128
Reputation: 511
More Pythonic way to write andSerch() will be:
from functools import reduce
def andSearch(inverseIndex, query):
return reduce(lambda x, y: x & y, [(inverseIndex[key]) for key in query])
Here we used reduce function to aggregate results of transitional calculations.
Also it may be useful to check if all items of query are in inverseIndex. Then our function will look like
from functools import reduce
def andSearch(inverseIndex, query):
if set(query) < set(inverseIndex.keys()):
return reduce(lambda x, y: x & y, [(inverseIndex[key]) for key in query])
else:
return False # or what ever is meaningful to return
Upvotes: 1
Reputation: 798536
Rewrite orSearch()
to use any()
to find any of the terms, and then derive andSearch()
by modifying your solution to use all()
instead to find all of the terms.
Upvotes: 2