Repository: pandas-dev/pandas

Issue:
setitem on empty DataFrame / Series casts to RangeIndex
I thought we had an issue for this, but couldn't find it.

```python
In [41]: df = pd.DataFrame(columns=['A'])

In [42]: df.index.dtype
Out[42]: dtype('O')

In [43]: df['A'] = []

In [44]: df.index.dtype
Out[44]: dtype('int64')

In [45]: df.index
Out[45]: RangeIndex(start=0, stop=0, step=1)
```

I this should still be empty an empty `Index` (though see https://github.com/pandas-dev/pandas/pull/16961 which proposes change `pd.Series()` to have that use a range index. Not sure if that's a good idea or not).

xref https://github.com/dask/dask/issues/2564


Discussion:
It's possible that adding an `and len(value)` to the `if` statement in https://github.com/pandas-dev/pandas/blob/ee6b1318ff07806ead79dac8119ad9ce580afe1c/pandas/core/frame.py#L3386-L3389

will fix things. That plus a test would make a good first PR.
I would like to fix this as my first PR! 

Resolving patch:
diff --git a/pandas/core/frame.py b/pandas/core/frame.py
--- a/pandas/core/frame.py
+++ b/pandas/core/frame.py
@@ -3095,7 +3095,7 @@ def _ensure_valid_index(self, value):
         passed value.
         """
         # GH5632, make sure that we are a Series convertible
-        if not len(self.index) and is_list_like(value):
+        if not len(self.index) and is_list_like(value) and len(value):
             try:
                 value = Series(value)
             except (ValueError, NotImplementedError, TypeError):


Test patch:
diff --git a/pandas/tests/frame/test_indexing.py b/pandas/tests/frame/test_indexing.py
--- a/pandas/tests/frame/test_indexing.py
+++ b/pandas/tests/frame/test_indexing.py
@@ -821,6 +821,14 @@ def test_setitem_empty_frame_with_boolean(self, dtype, kwargs):
         df[df > df2] = 47
         assert_frame_equal(df, df2)
 
+    def test_setitem_with_empty_listlike(self):
+        # GH #17101
+        index = pd.Index([], name="idx")
+        result = pd.DataFrame(columns=["A"], index=index)
+        result["A"] = []
+        expected = pd.DataFrame(columns=["A"], index=index)
+        tm.assert_index_equal(result.index, expected.index)
+
     def test_setitem_scalars_no_index(self):
         # GH16823 / 17894
         df = DataFrame()
diff --git a/pandas/tests/indexing/test_partial.py b/pandas/tests/indexing/test_partial.py
--- a/pandas/tests/indexing/test_partial.py
+++ b/pandas/tests/indexing/test_partial.py
@@ -442,10 +442,10 @@ def test_partial_set_empty_frame(self):
         # these work as they don't really change
         # anything but the index
         # GH5632
-        expected = DataFrame(columns=["foo"], index=Index([], dtype="int64"))
+        expected = DataFrame(columns=["foo"], index=Index([], dtype="object"))
 
         def f():
-            df = DataFrame()
+            df = DataFrame(index=Index([], dtype="object"))
             df["foo"] = Series([], dtype="object")
             return df
 
@@ -469,22 +469,21 @@ def f():
         expected["foo"] = expected["foo"].astype("float64")
 
         def f():
-            df = DataFrame()
+            df = DataFrame(index=Index([], dtype="int64"))
             df["foo"] = []
             return df
 
         tm.assert_frame_equal(f(), expected)
 
         def f():
-            df = DataFrame()
+            df = DataFrame(index=Index([], dtype="int64"))
             df["foo"] = Series(np.arange(len(df)), dtype="float64")
             return df
 
         tm.assert_frame_equal(f(), expected)
 
         def f():
-            df = DataFrame()
-            tm.assert_index_equal(df.index, Index([], dtype="object"))
+            df = DataFrame(index=Index([], dtype="int64"))
             df["foo"] = range(len(df))
             return df