BUG: Fix regression in is_list_like by aiudirog · Pull Request #43373 · pandas-dev/pandas (original) (raw)

is_list_like() used to use isinstance(obj, abc.Iterable) before #39852 where it was optimized for performance. This resulted in a regression where objects that explicitly declare __iter__ as None are considered "list like" but not instances of abc.Iterable.

Because the original original PR was focused on performance, here are the same timeit cases run on this PR:

In[1]: import numpy as np In[2]: from pandas._libs.lib import is_list_like In[3]: arr = np.array(0) In[4]: arr2 = np.array([0])

In[5]: %timeit is_list_like([]) 51.3 ns ± 0.231 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) <- master 56.3 ns ± 0.44 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) <- PR 153 ns ± 2.4 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) <- isinstance(obj, abc.Iterable)

In[6]: %timeit is_list_like(0) 117 ns ± 2.19 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) <- master 126 ns ± 2 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) <- PR 154 ns ± 1.18 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) <- isinstance(obj, abc.Iterable)

In[7]: %timeit is_list_like(arr) 49.5 ns ± 0.156 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) <- master 50.6 ns ± 0.14 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) <- PR 152 ns ± 1.12 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) <- isinstance(obj, abc.Iterable)

In[8]: %timeit is_list_like(arr2) 50.8 ns ± 1.36 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) <- master 51.5 ns ± 0.179 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) <- PR 151 ns ± 0.582 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) <- isinstance(obj, abc.Iterable)