For the one-line syntax, the else suite is required (e.g. ab.append(c) if c in ['a','b'] else pass for c in list(string)). However, statements are not permitted as operands in the syntax.
You're looking for list comprehensions (e.g. ab = [c if c in ['a','b'] else None for c in list(string)]). However, that could put None in your list, which I don't believe that you want. List comprehensions have special syntactic sugar for these situations. You simply move the test expression to the end (e.g. ab = [c for c in list(string) if c in ['a','b']]).
In your particular case, another approach is to use filter. This can be particularly helpful for situations in which the test function is lengthy or complicated. See the following for an example:
def is_valid_char(c):
return c in ['a','b','c','d','e','f','A','B','C','D','E','F']
ab = list(filter(is_valid_char, list(string)))
Lastly, strings are iterable, so there's no need to convert one to a list for this purpose (e.g. ab = filter(is_valid_char, string)).