Would be interesting to hear what would be the functional stand on this.
In a way a team may not need the players. Maybe teams are just identifiers, as are players, and we have a list of event relating players to teams. Then a function can get these events and compute the current list of players in a given team.
One way of doing it would be to use a record type, one part of which would be the list of players. This is analogous to the composition strategy in OO. You could then manipulate values of that record type using lenses.
The important question is what you actually want to do with this data. The thing that has always seemed crazy to me about OO is how you can have page-long discussions like this one without even talking about what the data is being used for. The notion instead is to "model the real world", which sends you off on a wild goose chase that is almost always unnecessary.
Classic functional programming doesn't cover oop: there's no subclassing, thus no issue with using a list to keep your players. Furthermore, pure functional code doesn't mutate, so invariants can't really be broken, unless you meddle with the internal representation, in a way which would confuse the existing codebase to handle lists.
So if you pick list as the implementation detail of your team type, then it will essentially be a list, and may be passed as such to list handling functions without issues. It'll be up to your code to handle the aftermath if your invariants were somehow broken in the process, which would be the proper thing to do. From the outside though, just like for any type, the implementation details shouldn't be exposed. For weakly typed languages, it should be documented to not rely on it.
Edit: I was just handling the original question from an functional stand point. Of course nbouscal solution is much more usable and robust. What would probably happen, if you follow an agile methodology, or some similarly incremental process of development, is that you'd probably start with a list, and as new functionalities would be added, the type would evolve to a tuple or a record including the list. Any function would then have to be updated accordingly. But at least the team type should be made abstract somehow, to hide implementation details.
In a way a team may not need the players. Maybe teams are just identifiers, as are players, and we have a list of event relating players to teams. Then a function can get these events and compute the current list of players in a given team.