BUG: Let MultiIndex.set_levels accept any iterable (#23273)
- [x] closes #23273
- [x] tests added and passed
- [x] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [x] whatsnew entry

Quite surprisingly, `is_list_like` accepts a wide range of iterables including non-subscriptable objects. Later in the code `set_levels` implicitly supposes that passed instance can return its 0'th element by index, which is not always the case, as provided in the example of the #23273.

To address the issue, a new helper function `is_subscriptable` is added, and if passed levels look like a list, but are not subscriptable, they are explicltly converted to a list with `list(levels)`
