Repository: pandas-dev/pandas

Issue:
BUG: iloc setitem indexing with list of lists
different results when mixed vs single dtypes

```
In [1]: df = DataFrame(dict(A = np.arange(5), B = np.arange(5,10)))

In [2]: df
Out[2]: 
   A  B
0  0  5
1  1  6
2  2  7
3  3  8
4  4  9

In [4]: df.iloc[2:4] = [[10,11],[12,13]]

In [5]: df
Out[5]: 
    A   B
0   0   5
1   1   6
2  10  11
3  12  13
4   4   9
```

```
In [6]: df = DataFrame(dict(A = list('abcde'), B = np.arange(5,10)))

In [7]:  df.iloc[2:4] = [['x',11],['y',13]]

In [8]: df
Out[8]: 
    A   B
0   a   5
1   b   6
2   x   y
3  11  13
4   e   9
```



Discussion:

Resolving patch:
diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py
--- a/pandas/core/indexing.py
+++ b/pandas/core/indexing.py
@@ -419,14 +419,20 @@ def can_do_equal_len():
                         else:
                             setter(item, np.nan)
 
-                # we have an equal len ndarray to our labels
-                elif isinstance(value, np.ndarray) and value.ndim == 2:
+                # we have an equal len ndarray/convertible to our labels
+                elif np.array(value).ndim == 2:
+
+                    # note that this coerces the dtype if we are mixed
+                    # GH 7551
+                    value = np.array(value,dtype=object)
                     if len(labels) != value.shape[1]:
                         raise ValueError('Must have equal len keys and value '
                                          'when setting with an ndarray')
 
                     for i, item in enumerate(labels):
-                        setter(item, value[:, i])
+
+                        # setting with a list, recoerces
+                        setter(item, value[:, i].tolist())
 
                 # we have an equal len list/ndarray
                 elif can_do_equal_len():


Test patch:
diff --git a/pandas/tests/test_indexing.py b/pandas/tests/test_indexing.py
--- a/pandas/tests/test_indexing.py
+++ b/pandas/tests/test_indexing.py
@@ -1272,7 +1272,6 @@ def test_iloc_setitem_series(self):
         result = df.iloc[:,2:3]
         assert_frame_equal(result, expected)
 
-    def test_iloc_setitem_series(self):
         s = Series(np.random.randn(10), index=lrange(0,20,2))
 
         s.iloc[1] = 1
@@ -1284,6 +1283,20 @@ def test_iloc_setitem_series(self):
         result = s.iloc[:4]
         assert_series_equal(result, expected)
 
+    def test_iloc_setitem_list_of_lists(self):
+
+        # GH 7551
+        # list-of-list is set incorrectly in mixed vs. single dtyped frames
+        df = DataFrame(dict(A = np.arange(5,dtype='int64'), B = np.arange(5,10,dtype='int64')))
+        df.iloc[2:4] = [[10,11],[12,13]]
+        expected = DataFrame(dict(A = [0,1,10,12,4], B = [5,6,11,13,9]))
+        assert_frame_equal(df, expected)
+
+        df = DataFrame(dict(A = list('abcde'), B = np.arange(5,10,dtype='int64')))
+        df.iloc[2:4] = [['x',11],['y',13]]
+        expected = DataFrame(dict(A = ['a','b','x','y','e'], B = [5,6,11,13,9]))
+        assert_frame_equal(df, expected)
+
     def test_iloc_getitem_multiindex(self):
         mi_labels = DataFrame(np.random.randn(4, 3), columns=[['i', 'i', 'j'],
                                                               ['A', 'A', 'B']],