С помощью __str__ возвращать список - плохая идея, но строку с сериализованным списком - почему нет?
Я обычно как-то так делаю:
def __repr__(self):
return f'{type(self).__name__}({self.name!r}, {self.first_name!r}, {self.last_name!r})'
Если __str__ не описан отдельно, то будет вызываться __repr__ при вызове str(obj).
Можно и в виде списка как вы хотите:
def __str__(self):
return f'{[self.name, self.first_name, self.last_name]!r}'