Python 中哪种数据类型被视为“类列表”?

Yan*_*dle 9 python dictionary python-3.x pandas

在 Pandas 文档中Series.isin(values)他们指出:

值:设置或类似列表

什么被认为是类似列表的?对于 Python 字典temp_dicttemp_dict.keys()和会temp_dict.values()被视为类似列表吗?

use*_*ica 14

“类列表”不是标准的 Python 术语。谷歌搜索pandas list-like出现了pandas.api.types.is_list_like,但文档只是说

检查对象是否类似于列表。

被视为类似列表的对象包括 Python 列表、元组、集合、NumPy 数组和 Pandas Series。

但是,字符串和日期时间对象不被视为类似列表。

这并不是一个真正的规格。因此,作为最后的手段,我们转向源代码,在进行大量导入和别名之后,我们最终找到了这个函数

cdef bint c_is_list_like(object obj, bint allow_sets) except -1:
    # first, performance short-cuts for the most common cases
    if util.is_array(obj):
        # exclude zero-dimensional numpy arrays, effectively scalars
        return not cnp.PyArray_IsZeroDim(obj)
    elif isinstance(obj, list):
        return True
    # then the generic implementation
    return (
        # equiv: `isinstance(obj, abc.Iterable)`
        getattr(obj, "__iter__", None) is not None and not isinstance(obj, type)
        # we do not count strings/unicode/bytes as list-like
        # exclude Generic types that have __iter__
        and not isinstance(obj, (str, bytes, _GenericAlias))
        # exclude zero-dimensional duck-arrays, effectively scalars
        and not (hasattr(obj, "ndim") and obj.ndim == 0)
        # exclude sets if allow_sets is False
        and not (allow_sets is False and isinstance(obj, abc.Set))
    )
Run Code Online (Sandbox Code Playgroud)

因此,如果 Pandas 通过了这一系列复杂的检查,则将其视为类似对象列表。

  • 如果一个对象是 0 维 NumPy 数组,则它不是类似列表的。
  • 否则,如果它是一个列表,它就是类似列表的。
  • 否则,它需要通过以下所有检查才能成为列表:
    • 它需要有一个__iter__不是 的属性None
    • 它不需要是一种类型。
    • 它不必是字符串、字节串或“通用别名”(用于某些typing模块事物的类型)。
    • 它不需要有ndim等于 0 的属性。
    • 在某些情况下,Pandas 将不允许 的实例collections.abc.Set,这些实例是集合、冻结集和某些其他类似集合的对象。(abccollections.abc这儿。)

这意味着 Pandas 认为大多数可迭代对象都是类似列表的。字符串、字节串、泛型别名和可迭代类型对象(如Enum 类)被排除,其中关于排除可迭代类型对象的部分可能是一个错误 - 代码试图排除实例可迭代的不可迭代类型对象。

0 维数组和ndim==0检查尝试排除其类型的正维实例可迭代但 0 维实例不可迭代的对象。

collections.abc.Set有时会排除集合和其他子类,但Series.isin不会传递标志来排除它们。


ifl*_*ly6 6

如果您查看 Pandas 文档,您会发现一个函数可以确定某些内容是否为 list 之类的。如果您进行大量搜索和搜索,您最终会得到一个定义该函数的 C 版本的pyx文件:

cdef bint c_is_list_like(object obj, bint allow_sets) except -1:
    # first, performance short-cuts for the most common cases
    if util.is_array(obj):
        # exclude zero-dimensional numpy arrays, effectively scalars
        return not cnp.PyArray_IsZeroDim(obj)
    elif isinstance(obj, list):
        return True
    # then the generic implementation
    return (
        # equiv: `isinstance(obj, abc.Iterable)`
        getattr(obj, "__iter__", None) is not None and not isinstance(obj, type)
        # we do not count strings/unicode/bytes as list-like
        # exclude Generic types that have __iter__
        and not isinstance(obj, (str, bytes, _GenericAlias))
        # exclude zero-dimensional duck-arrays, effectively scalars
        and not (hasattr(obj, "ndim") and obj.ndim == 0)
        # exclude sets if allow_sets is False
        and not (allow_sets is False and isinstance(obj, abc.Set))
    )
Run Code Online (Sandbox Code Playgroud)

这是有很多条件的。numpy它在允许所有列表之前排除零维数组。剩下的必须是可迭代的,但不是字符串、字节或泛型,也不是ndim == 0,并且如果设置了该标志,则不是集合。