Shorter MultiIndex representation
State: closed

- [x] closes #12423
- [x] tests added / passed
- [x] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [x] whatsnew entry

MultiIndex can currently have quite long repr output, which may also take a long time to print.

This PR makes the MultiIndex repr output similar in style to other Index reprs. An alternative would be to output ``labels`` and ``levels`` by supplying ``pd.options.display.max_seq_items`` to ``ibase.default_pprint``, but IMO this is better, as it's more similar to other axis repr's.

#### Example with few items in index

```python
>>> pd.MultiIndex(levels=[['a', 'b'], ['A', 'B']], labels=[[0, 0, 1, 1], [0, 0, 0, 1]])
MultiIndex(levels=[['a', 'b'], ['A', 'B']],
           labels=[[0, 0, 1, 1], [0, 0, 0, 1]])
```

#### Example with many items in index

```python
>>> idx=range(1000)
>>> pd.MultiIndex.from_arrays([idx, idx])
MultiIndex(levels=[[  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
                    ...
                    990, 991, 992, 993, 994, 995, 996, 997, 998, 999],
                   [  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
                    ...
                    990, 991, 992, 993, 994, 995, 996, 997, 998, 999],
                   ],
           labels=[[  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
                    ...
                    990, 991, 992, 993, 994, 995, 996, 997, 998, 999],
                   [  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
                    ...
                    990, 991, 992, 993, 994, 995, 996, 997, 998, 999],
                   ])
```

If this approach is ok, I can write up whatsnew, tests etc. but would appreciate feedback before I do that.

EDIT: tests and whatsnew added.


Labels:
name: Enhancement
name: Output-Formatting
description: __repr__ of pandas objects, to_string
name: MultiIndex

Comments:
Hello @topper-123! Thanks for updating the PR.





Cheers ! There are no PEP8 issues in this Pull Request. :beers: 

##### Comment last updated on May 21, 2018 at 19:59 Hours UTC
# [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/21145?src=pr&el=h1) Report
> Merging [#21145](https://codecov.io/gh/pandas-dev/pandas/pull/21145?src=pr&el=desc) into [master](https://codecov.io/gh/pandas-dev/pandas/commit/81358e862022cedbac009985abac5135a873dde3?src=pr&el=desc) will **decrease** coverage by `<.01%`.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/pandas-dev/pandas/pull/21145/graphs/tree.svg?src=pr&width=650&token=eZ4WkYLtcO&height=150)](https://codecov.io/gh/pandas-dev/pandas/pull/21145?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master   #21145      +/-   ##
==========================================
- Coverage   91.84%   91.84%   -0.01%     
==========================================
  Files         153      153              
  Lines       49502    49512      +10     
==========================================
+ Hits        45463    45472       +9     
- Misses       4039     4040       +1
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `90.23% <100%> (-0.01%)` | :arrow_down: |
| #single | `41.87% <9.09%> (-0.01%)` | :arrow_down: |

| [Impacted Files](https://codecov.io/gh/pandas-dev/pandas/pull/21145?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pandas/core/indexes/multi.py](https://codecov.io/gh/pandas-dev/pandas/pull/21145/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvaW5kZXhlcy9tdWx0aS5weQ==) | `95.11% <100%> (+0.04%)` | :arrow_up: |
| [pandas/io/formats/printing.py](https://codecov.io/gh/pandas-dev/pandas/pull/21145/diff?src=pr&el=tree#diff-cGFuZGFzL2lvL2Zvcm1hdHMvcHJpbnRpbmcucHk=) | `88.49% <0%> (-0.89%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/21145?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/21145?src=pr&el=footer). Last update [81358e8...00c2297](https://codecov.io/gh/pandas-dev/pandas/pull/21145?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

> output labels and levels according to pd.options.display.max_seq_items, but IMO this is better, 

yes this parameter needs to be used to control the len
``pd.options.display.max_seq_items`` is being used in ``Index._format_data``, so it also works here:

```python
>>> pd.options.display.max_seq_items
100
>>> idx=range(101)
>>> pd.MultiIndex.from_arrays([idx, idx])  # abbreviates
MultiIndex(levels=[[  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
                    ...
                     91,  92,  93,  94,  95,  96,  97,  98,  99, 100],
                   [  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
                    ...
                     91,  92,  93,  94,  95,  96,  97,  98,  99, 100],
                   ],
           labels=[[  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
                    ...
                     91,  92,  93,  94,  95,  96,  97,  98,  99, 100],
                   [  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
                    ...
                     91,  92,  93,  94,  95,  96,  97,  98,  99, 100],
                   ])
>>> idx=range(100)
>>> pd.MultiIndex.from_arrays([idx, idx])  # doesn't abbreviate
MultiIndex(levels=[[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
                    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
                    30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
                    45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
                    60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
                    75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
                    90, 91, 92, 93, 94, 95, 96, 97, 98, 99],
                   [ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
                    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
                    30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
                    45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
                    60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
                    75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
                    90, 91, 92, 93, 94, 95, 96, 97, 98, 99],
                   ],
           labels=[[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
                    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
                    30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
                    45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
                    60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
                    75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
                    90, 91, 92, 93, 94, 95, 96, 97, 98, 99],
                   [ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
                    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
                    30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
                    45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
                    60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
                    75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
                    90, 91, 92, 93, 94, 95, 96, 97, 98, 99],
                   ])
```

If ``pd.options.display.max_seq_items`` changes, the point of abbreviation changes as well.
Is this ok?
Closed in favor of #22511.