У вас уже есть свой ответ, но я хотел бы добавить, что не все знаки препинания должны быть прикреплены к левой стороне. Если вы хотите иметь дело с более общими предложениями, у вас могут быть, например, круглые скобки или апострофы, и вы не захотите получить что-то вроде:
Это отличный фильм (лучшее, что я видел)
Я бы сказал, что бессмысленно создавать какие-то неприятные однострочники, просто делать это самым питонским способом. Если вам не нужно сверхбыстрое решение, вы можете рассмотреть его пошаговое решение, например:
import re
s = ['It', "'", 's', 'a', 'great', 'movie',
'(', 'best', 'I', "'", 've', 'seen', ')']
s = " ".join(s) # join normally
s = re.sub(" ([,.;\)])", lambda m: m.group(1), s) # stick to left
s = re.sub("([\(]) ", lambda m: m.group(1), s) # stick to right
s = re.sub(" ([']) ", lambda m: m.group(1), s) # join both sides
print s # It's a great movie (best I've seen)
Он довольно гибкий, и вы можете указать, какая пунктуация обрабатывается каждым правилом ... Хотя в нем 4 строки, поэтому вам может не понравиться. Независимо от того, какой метод вы выберете, вероятно, будут некоторые предложения, которые не будут работать правильно и нуждаются в особом случае, так что в любом случае использование одной строки может быть просто плохим выбором.
РЕДАКТИРОВАТЬ: На самом деле, вы можете заключить вышеупомянутое решение на одну строку, но, как уже было сказано, я уверен, что есть еще случаи для рассмотрения:
print re.sub("( [,.;\)]|[\(] | ['] )", lambda m: m.group(1).strip(), " ".join(s))