Nice post overall, but I take issue with a couple of the examples. First, the YoutubeSearch class has no reason to be a class. It wants to be a function:
def youtube_search(term):
url = 'https://gdata.youtube.com/feeds/api/videos'
params = {'q': term, 'alt': 'json', 'orderby': 'relevance', 'v': '2'}
r = requests.get(url, params=params)
r.raise_for_status() # 4xx and 5xx replies raise exception
for video in r.json.get('feed').get('entry'):
yield {
'title': video.get('title').get('$t'),
'url': video.get('link')[0].get('href'),
}
The ExpressiveList's __sub__() method, as written in the article, requires O(n*k) time to remove k things from a list of length n. By using a set of things to remove, we can get that down to O(n+k): class ExpressiveList(list):
def __sub__(self, other):
if isinstance(other, list):
other_set = set(other)
return ExpressiveList(x for x in self if x not in other_set)
else:
return ExpressiveList(x for x in self if x != other)