Repository: modin-project/modin

Issue:
`concat` does not accept non-subscriptable objects as parameters
<!--
General questions should be asked on the mailing list modin-dev@googlegroups.com.

Before submitting an issue, please fill out the following form.
-->

### System information
- **OS Platform and Distribution (e.g., Linux Ubuntu 16.04)**: OSX
- **Modin installed from (source or binary)**: source
- **Modin version**: master
- **Python version**: 3.6
- **Exact command to reproduce**: `pd.concat(dict_vals.values(), dict_vals.keys())`

<!--
You can obtain the Modin version with

python -c "import modin; print(modin.__version__)"
-->

### Describe the problem
pandas supports this behavior, but because of how metadata is computed internally, Modin does not.
<!-- Describe the problem clearly here. -->

### Source code / logs
```python
import modin.pandas as pd 
import numpy as np
frame_data = np.random.randint(0, 100, size=(2**18, 2**8)) 
df = pd.DataFrame(frame_data).add_prefix("col") 
a = {'c':df.copy(), "b":df.copy()}
pd.concat(a.values(), keys=a.keys())
```

Error thrown:

```
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-ba24112d4dde> in <module>
----> 1 pd.concat(a.values(), keys=a.keys())

~/software_builds/modin/modin/pandas/concat.py in concat(objs, axis, join, join_axes, ignore_index, keys, levels, names, verify_integrity, sort, copy)
     98         new_idx_labels = {
     99             keys[i]: objs[i].index if axis == 0 else objs[i].columns
--> 100             for i in range(len(objs))
    101         }
    102         print(new_idx_labels)

~/software_builds/modin/modin/pandas/concat.py in <dictcomp>(.0)
     98         new_idx_labels = {
     99             keys[i]: objs[i].index if axis == 0 else objs[i].columns
--> 100             for i in range(len(objs))
    101         }
    102         print(new_idx_labels)

TypeError: 'dict_keys' object does not support indexing
```
<!-- Include any logs or source code that would be helpful to diagnose the problem. If including tracebacks, please include the full traceback. Large logs and files should be attached. Try to provide a reproducible test case that is the bare minimum necessary to generate the problem. -->



Discussion:

Resolving patch:
diff --git a/modin/pandas/concat.py b/modin/pandas/concat.py
--- a/modin/pandas/concat.py
+++ b/modin/pandas/concat.py
@@ -96,10 +96,8 @@ def concat(
     if keys is not None:
         objs = [objs[i] for i in range(min(len(objs), len(keys)))]
         new_idx_labels = {
-            keys[i]: objs[i].index if axis == 0 else objs[i].columns
-            for i in range(len(objs))
+            k: v.index if axis == 0 else v.columns for k, v in zip(keys, objs)
         }
-        print(new_idx_labels)
         tuples = [(k, o) for k, obj in new_idx_labels.items() for o in obj]
         new_idx = pandas.MultiIndex.from_tuples(tuples)
     else:


Test patch:
diff --git a/modin/pandas/test/test_concat.py b/modin/pandas/test/test_concat.py
--- a/modin/pandas/test/test_concat.py
+++ b/modin/pandas/test/test_concat.py
@@ -2,8 +2,10 @@
 from __future__ import division
 from __future__ import print_function
 
+import numpy as np
 import pytest
 import pandas
+
 import modin.pandas as pd
 from modin.pandas.utils import from_pandas, to_pandas
 
@@ -172,3 +174,15 @@ def test_ignore_index_concat():
         pd.concat([df, df2], ignore_index=True),
         pandas.concat([df, df2], ignore_index=True),
     )
+
+
+def test_concat_non_subscriptable_keys():
+    frame_data = np.random.randint(0, 100, size=(2 ** 10, 2 ** 6))
+    df = pd.DataFrame(frame_data).add_prefix("col")
+    pdf = pandas.DataFrame(frame_data).add_prefix("col")
+
+    modin_dict = {"c": df.copy(), "b": df.copy()}
+    pandas_dict = {"c": pdf.copy(), "b": pdf.copy()}
+    modin_result = pd.concat(modin_dict.values(), keys=modin_dict.keys())
+    pandas_result = pandas.concat(pandas_dict.values(), keys=pandas_dict.keys())
+    modin_df_equals_pandas(modin_result, pandas_result)