All answers are correct, but in case your sentence is quite long and the mapping-dictionary rather small, you should think of iterating over the items (key-value pairs) of the dictionary and apply str.replace to the original sentence.
The code as suggested by the others. It takes 6.35 µs per loop.
%%timeit
search = "you don't need a dog. but if you like dogs, you should think of getting one for your own. Or a cat?"
mapping = {"don't": "do not" }
search = ' '.join([mapping.get(i, i) for i in search.split()])
Let's try using str.replace instead. It takes 633 ns per loop.
%%timeit
search = "you don't need a dog. but if you like dogs, you should think of getting one for your own. Or a cat?"
mapping = {"don't": "do not" }
for key, value in mapping.items():
search = search.replace(key, value)
And let's use Python3 list comprehension. So we get the fastest version that takes 1.09 µs per loop.
%%timeit
search = "you don't need a dog. but if you like dogs, you should think of getting one for your own. Or a cat?"
mapping = {"don't": "do not" }
search = [search.replace(key, value) for key, value in mapping.items()][0]
You see the difference? For your short sentence the first and the third code are about the same speed. But the longer the sentence (search string) gets, the more obvious the difference in performance is.
Result string is:
'you do not need a dog. but if you like dogs, you should think of getting one for your own. Or a cat?'
Remark: str.replace would also replace occurrences within long concatenated words. One needs to ensure that replacement is done for full words only. I guess there are options for str.replace. Another idea is using regular expressions as explained in this posting as they also take care of lower and upper cases. Trailing white spaces in your lookup dictionary won’t work since you won’t find occurrences at the beginning or on the end of a sentence.