python从字符串创建切片对象

时间:2009-03-25 09:23:52

标签: python indexing slice

我想从字符串创建切片对象;现在唯一的方法似乎是通过一个繁琐的hacky评估声明

class getslice:
    def __getitem__(self, idx): return idx[0]
eval("getslice()[%s, 1]" %(":-1"))

提前感谢。

编辑:很抱歉,如果原始提示不清楚,则此情况下的输入为“: - 1”。关键在于解析字符串。 Ignacio Vazquez-Abrams的回答至少解决了这个问题(并且似乎也适用于反向索引),但我认为如果不是概念上干净的话,上面的解决方案仍然更清晰(如果Python改变了切片语法,它将正常工作)。 / p>

9 个答案:

答案 0 :(得分:3)

如果你想要一个切片对象,为什么不直接实例化?

s = slice(start, stop, step)

“从字符串创建”是什么意思?

答案 1 :(得分:3)

slice(*map(lambda x: int(x.strip()) if x.strip() else None, mystring.split(':')))

根据要求,将其从评论部分中删除。

答案 2 :(得分:2)

slice(*[{True: lambda n: None, False: int}[x == ''](x) for x in (mystring.split(':') + ['', '', ''])[:3]])

答案 3 :(得分:2)

我最终在这里,因为我希望我的脚本接受类似python的splice参数并将其呈现为整数列表,我使用的函数看起来像是回答了OP的问题:

# create a slice object from a string
def get_slice_obj(slicearg):
    slice_ints = tuple([ int(n) for n in slicearg.split(':') ])
    return apply(slice, slice_ints)

def ints_from_slicearg(slicearg):
    slice_obj = get_slice_obj(slicearg)
    return(range(slice_obj.start or 0, slice_obj.stop or -1, slice_obj.step or 1))

for t in ['1', '1:3', '4:9:2']:
    print t, "=>", ints_from_slicearg(t)

输出:

1 => [0]
1:3 => [1, 2]
4:9:2 => [4, 6, 8]

答案 4 :(得分:1)

这是另一种方法(只是这里发布的其他方法的合并):

def make_slice(expr):
    def to_piece(s):
        return s and int(s) or None
    pieces = map(to_piece, expr.split(':'))
    if len(pieces) == 1:
        return slice(pieces[0], pieces[0] + 1)
    else:
        return slice(*pieces)

示例用法:

In [1]: make_slice(':')
Out[1]: slice(None, None, None)

In [2]: make_slice(':-2')
Out[2]: slice(None, -2, None)

In [3]: x = [1, 2, 3]

In [4]: x[make_slice('::-1')]
Out[4]: [3, 2, 1]

答案 5 :(得分:1)

伊格纳西奥·巴斯克斯(Ignacio Vazquez-Abrams)的单行代码很短,但几乎不可读,并且处理与slice不一致的单个数字。这样会尝试以一种更简洁的方式对其进行解析。

def parse_slice(value):
    """
    Parses a `slice()` from string, like `start:stop:step`.
    """
    if value:
        parts = value.split(':')
        if len(parts) == 1:
            # slice(stop)
            parts = [None, parts[0]]
        # else: slice(start, stop[, step])
    else:
        # slice()
        parts = []
    return slice(*[int(p) if p else None for p in parts])
# unit tests:
try:
    assert parse_slice('')
    assert False, 'It should raise TypeError'
except TypeError:
    pass
assert parse_slice('2') == slice(2)
assert parse_slice('2:3') == slice(2, 3)
assert parse_slice(':3') == slice(None, 3)
assert parse_slice(':') == slice(None, None)
assert parse_slice('2:') == slice(2, None)
assert parse_slice('2:3:4') == slice(2, 3, 4)
assert parse_slice(':3:4') == slice(None, 3, 4)
assert parse_slice('2::4') == slice(2, None, 4)
assert parse_slice('2:3:') == slice(2, 3, None)
assert parse_slice('::4') == slice(None, None, 4)
assert parse_slice('2::') == slice(2, None, None)
assert parse_slice('::') == slice(None, None, None)
assert parse_slice('-12:-13:-14') == slice(-12, -13, -14)
assert parse_slice('2:3:-4') == slice(2, 3, -4)
try:
    parse_slice('1:2:3:4')
    assert False, 'It should raise TypeError'
except TypeError:
    pass

答案 6 :(得分:0)

如何处理(对于简单的非空切片间隔):

sliceStr = "3:8"
mySlice = slice( *map(int, sliceStr.split(':') ) )

答案 7 :(得分:-1)

切片对象通常使用下标表示法创建,此表示法在内部使用slice(),如slice() documentation所述。你想要做的是:

your_string[start:end]

来自the python tutorial

  

字符串可以下标(索引);   就像在C中,第一个字符   string有下标(index)0   不是单独的字符类型;一个   字符只是一串大小   一。就像在Icon中一样,子串也可以   用切片表示法指定:两个   由冒号分隔的指数。

>>> word = 'Help' + 'A' 
>>> word[4]
'A'
>>> word[0:2]
'He'
>>> word[2:4]
'lp'
  

切片索引具有有用的默认值;一个   省略第一个索引默认为零,   省略的第二个索引默认为   被切片的字符串的大小。

>>> word[:2]    # The first two characters
'He'
>>> word[2:]    # Everything except the first two characters
'lpA'

答案 8 :(得分:-1)

我的解决方案从字符串my gist解析numpy样式高级索引。 尽管这是一篇过时的文章,但这是我唯一可以找到的关于该主题的文章。希望对您有所帮助。

根据建议,我将代码粘贴到此处,这可能会有点长...代码用法是(假设a是一个类似数组的对象):a[parse_slice('1')]给出{{1 }}; a[1]给出a[parse_slice('2:,-1')];等

a[2:,-1]