python 基于单位的闭区间切片到基于零的半开区间切片,支持反向步幅

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python 基于单位的闭区间切片到基于零的半开区间切片,支持反向步幅相关的知识,希望对你有一定的参考价值。

# -*- coding: utf-8 -*-
import itertools


def getint(s):
    """
    Unit-based integer (neg or pos, but not zero)
    """
    if s.strip() == '':
        return None
    try:
        value = int(s)
        if value != 0:
            return value
    except ValueError:
        pass


def unit_to_zero_based_slice(slicestr):
    """
    Convert a unit-based, close interval slice string into a 
    zero-based half-open interval slice tuple
    :returns: (start, stop, step) used to create a slice object

    >>> unit_to_zero_based_slice('2')
    (1, 2,)
    >>> unit_to_zero_based_slice('-1')
    (-1, None,)
    >>> unit_to_zero_based_slice('-3')
    (-3, -2,)
    >>> unit_to_zero_base_slice('2:1:-1')
    (2, None, -1,)
    >>> unit_to_zero_base_slice('4:-2:-1')
    (4, -3, -1,)
    >>> unit_to_zero_base_slice('4:2:-1')
    (4, 0, -1,)
    >>> unit_to_zero_base_slice('2:9:2')
    (1, 9, 2,)
    >>> unit_to_zero_base_slice('2:-4')
    (1, -3,)

    """
    START, STOP, STEP = range(3)
    slice_ = [getint(s) for s in slicestr.split(':')]
    slice_length = len(slice)
    if slice_length == 1:
        # slice item
        if slice_[START] and slice_[START] > 0:
            slice_.insert(0, slice_[START] - 1)
        elif slice_[START] == -1:
            slice_.append(None)
        elif slice_[START]:
            slice_.append(slice_[START] + 1)
    elif slice_length > 1:
        # slice range
        if slice_length > 2 and slice_[STEP] < 0 and slice_[STOP] is not None:
            # reverse stride
            if slice_[STOP] == 1:
                slice_[STOP] = None
            elif slice_[STOP] < 0:
                slice_[STOP] -= 1
            else:
                slice_[STOP] -= 2
        else:
            # forward stride
            if slice_[START] and slice_[START] > 0:
                slice_[START] -= 1
            if slice_[STOP] and slice_[STOP] < 0:
                slice_[STOP] = None if slice_[STOP] == -1 else slice_[STOP] + 1
    return tuple(slice_)


def slicedlist():
    pass


if __name__ == '__main__':
    row = ['a1', 'a2', 'a3', 'a4']
    starts = list(range(-4, +4)) + [None]
    stops = starts[:]
    steps = list(range(-4,0))
    for start, stop, step in itertools.product(starts, stops, steps):
        if step != 0:
            unit_slice_str = ':'.join([str(start), str(stop), str(step)])
            zero_slice_tuple = unit_to_zero_base_slice(unit_slice_str)
            sliced_row = row[slice(*zero_slice_tuple)]
            #print('{:<15} {!r:<20} {}'.format(unit_slice_str, zero_slice_tuple, sliced_row))
            print('"{}","{!r}","{!r}"'.format(unit_slice_str, zero_slice_tuple, sliced_row))

以上是关于python 基于单位的闭区间切片到基于零的半开区间切片,支持反向步幅的主要内容,如果未能解决你的问题,请参考以下文章

random模块

[SDOI2008]校门外的区间

python学习——pandas库的使用,仅需要这一篇就足够了

开区间 (数学用语)

列表切片截取

Python 学习笔记Python字符串