1

在 Python 中使用,和类似的可迭代对象实现类似str.strip()行为的方法是什么?listtuple

例子:

str.strip()-喜欢

>>> lst = ['\t', 0, 'a', ' ', 0, '\n', '\n', '', '\t']
>>> list_strip(lst)
... [0, 'a', ' ', 0]
>>> list_strip(lst, elements=(0, '\n', '', ' ', '\t'))
... ['a']

str.lstrip()-喜欢

>>> lst = ['\t', 0, 'a', ' ', 0, '\n', '\n', '', '\t']
>>> list_lstrip(lst)
... [0, 'a', ' ', 0, '\n', '\n', '', '\t']
>>> list_lstrip(lst, elements=(0, '\n', '', ' ', '\t'))
... ['a', ' ', 0, '\n', '\n', '', '\t']

str.rstrip()-喜欢

>>> lst = ['\t', 0, 'a', ' ', 0, '\n', '\n', '', '\t']
>>> list_rstrip(lst)
... ['\t', 0, 'a', ' ', 0]
>>> list_rstrip(lst, elements=(0, '\n', '', ' ', '\t'))
... ['\t', 0, 'a']

实现功能的原型如下

def set_force_iterable(val):
    if type(val) is str:
        return [val, ]
    else:
        try:
            iter(val)
            return val
        except TypeError:
            return [val, ]


def list_rstrip(lst, elements=None):
    '''Return a *copy* of the list or new tuple with trailing whitespace removed.

    Like :func:`str.rsrtip`.

    Parameters
    ----------
    lst : list or tuple
        List or tuple to be stripped.
    elements : iterable or None (default None)
        Elements to be stripped. Default None: strip all whitespaces.

    Returns
    -------
    list or tuple
        Return a *copy* of the list or new tuple with trailing whitespace removed.
        If elements is given and not None, remove values in elements instead.

    Examples
    --------
    >>> lst = ['\t', 0, 'a', ' ', 0, '\n', '\n', '', '\t']
    >>> list_rstrip(lst)
    ... ['\t', 0, 'a', ' ', 0]
    >>> list_rstrip(lst, elements=(0, '\n', '', ' ', '\t'))
    ... ['\t', 0, 'a']
    '''
    assert isinstance(lst, list) or isinstance(lst, tuple), '`lst` is not list or tuple'
    if elements is None:
        elements = ("", " ", "\t", "\n")
    else:
        elements = set_force_iterable(elements)

    if len(lst) == 0 or (len(lst) == 1 and lst[0] in elements):
        if isinstance(lst, list):
            return []
        else:
            return ()
    else:
        if lst[-1] not in elements:
            if isinstance(lst, list):
                return lst.copy()
            else:
                return lst
        prev_will_removed = True
        for i, el in enumerate(reversed(lst)):
            if not prev_will_removed or el not in elements:
                break
        return lst[:-i]


def list_lstrip(lst, elements=None):
    '''Return a *copy* of the list or new tuple with leading whitespace removed.

    Like :func:`str.lsrtip`.

    Parameters
    ----------
    lst : list or tuple
        List or tuple to be stripped.
    elements : iterable or None (default None)
        Elements to be stripped. Default None: strip all whitespaces.

    Returns
    -------
    list or tuple
        Return a *copy* of the list or new tuple with leading whitespace removed.
        If elements is given and not None, remove values in elements instead.

    Examples
    --------
    >>> lst = ['\t', 0, 'a', ' ', 0, '\n', '\n', '', '\t']
    >>> list_lstrip(lst)
    ... [0, 'a', ' ', 0, '\n', '\n', '', '\t']
    >>> list_lstrip(lst, elements=(0, '\n', '', ' ', '\t'))
    ... ['a', ' ', 0, '\n', '\n', '', '\t']
    '''
    assert isinstance(lst, list) or isinstance(lst, tuple), '`lst` is not list or tuple'

    if elements is None:
        elements = ("", " ", "\t", "\n")
    else:
        elements = set_force_iterable(elements)

    if len(lst) == 0 or (len(lst) == 1 and lst[0] in elements):
        if isinstance(lst, list):
            return []
        else:
            return ()
    else:
        if lst[0] not in elements:
            if isinstance(lst, list):
                return lst.copy()
            else:
                return lst
        prev_will_removed = True
        for i, el in enumerate(lst):
            if not prev_will_removed or el not in elements:
                break
        return lst[i:]


def list_strip(lst, elements=None):
    '''Return a **copy** of the list or new tuple with leading and trailing whitespace removed.

    Like :func:`str.srtip`.

    Parameters
    ----------
    lst : list or tuple
        List or tuple to be stripped.
    elements : iterable or None (default None)
        Elements to be stripped. Default None: strip all whitespaces.

    Returns
    -------
    list or tuple
        Return a **copy** of the list or new tuple with leading and trailing whitespace removed.
        If elements is given and not None, remove values in elements instead.

    Examples
    --------
    >>> lst = ['\t', 0, 'a', ' ', 0, '\n', '\n', '', '\t']
    >>> list_strip(lst)
    ... [0, 'a', ' ', 0]
    >>> list_strip(lst, elements=(0, '\n', '', ' ', '\t'))
    ... ['a']
    '''
    assert isinstance(lst, list) or isinstance(lst, tuple), '`lst` is not list or tuple'

    if elements is None:
        elements = ("", " ", "\t", "\n")
    else:
        elements = set_force_iterable(elements)

    if len(lst) == 0 or (len(lst) == 1 and lst[0] in elements):
        if isinstance(lst, list):
            return []
        else:
            return ()
    else:
        return list_lstrip(list_rstrip(lst, elements=elements), elements=elements)
4

1 回答 1

1

作为一个简单的替代方案,您可以使用列表切片:

def _first_index(lst):
    return next(i for i, s in enumerate(lst) if not isinstance(s, str) or (s and not s.isspace()))

def list_strip(lst):
    return lst[_first_index(lst):-_first_index(reversed(lst))]

def list_lstrip(lst):
    return lst[_first_index(lst):]

def list_rstrip(lst):
    return lst[:-_first_index(reversed(lst))]

用法:

lst = ['\t', 0, 'a', ' ', 0, '\n', '\n', '', '\t']
print(lst)
print(list_strip(lst))
print(list_lstrip(lst))
print(list_rstrip(lst))

输出:

['\t', 0, 'a', ' ', 0, '\n', '\n', '', '\t']
[0, 'a', ' ', 0]
[0, 'a', ' ', 0, '\n', '\n', '', '\t']
['\t', 0, 'a', ' ', 0]

如果要手动设置要过滤的元素,则需要更改条件_find_index()并为所有函数添加附加参数:

_fitered_chars = {"", " ", "\t", "\n"}
def _first_index(lst, elements=_fitered_chars):
    return next(i for i, s in enumerate(lst) if s not in elements)

def list_strip(lst, elements=_fitered_chars):
    return lst[_first_index(lst, elements):-_first_index(reversed(lst), elements)]

def list_lstrip(lst, elements=_fitered_chars):
    return lst[_first_index(lst, elements):]

def list_rstrip(lst, elements=_fitered_chars):
    return lst[:-_first_index(reversed(lst), elements)]

PS Code 很清楚,但如果您需要任何解释,请随时在评论中提问。

于 2020-08-21T11:12:57.037 回答