在[:index]上使用动态索引列出切片

时间:2015-05-13 17:20:25

标签: python list slice

我需要使用负动态索引([: - index])对列表进行切片。这很容易,直到我意识到如果我的动态索引的值为0,则没有返回任何项目,而是返回整个列表。我怎样才能以索引为0的方式实现它,它返回整个字符串? 我的代码很长很复杂,但基本上这个例子显示了问题:

    arr='test text'
    index=2
    print arr[:-index]
    >>'test te'    #Entire string minus 2 from the right
    index=1
    print arr[:-index]
    >>'test tex'    #Entire string minus 1 from the right
    index=0
    print arr[:-index]
    >>''           #I would like entire string minus 0 from the right

注意:我使用的是Python 2.7。

4 个答案:

答案 0 :(得分:8)

另一种有趣的解决方案。

>>> arr = [1, 2, 3]
>>> index = 0
>>> arr[:-index or None]
[1, 2, 3]
>>> index = 1
>>> arr[:-index or None]
[1, 2]

为了在字符串等不可变序列类型上获得更高的性能,通过在切片操作之前检查索引的值,可以避免在索引为0的情况下完全切片序列。

以下是三个在性能方面进行测试的功能:

def shashank1(seq, index):
    return seq[:-index or None]

def shashank2(seq, index):
    return index and seq[:-index] or seq

def shashank3(seq, index):
    return seq[:-index] if index else seq

在index为0的情况下,后两者应该更快,但在其他情况下可能更慢(或更快)。

更新了基准代码: http://repl.it/oA5

注意:结果在很大程度上取决于Python的实现。

答案 1 :(得分:6)

它可以消除切片表示法的清晰度,但你可以做到

>>> arr[: len(arr) - 2]
'test te'
>>> arr[: len(arr) - 1]
'test tex'
>>> arr[: len(arr) - 0]
'test text'

答案 2 :(得分:4)

您可以使用None而不是0来获取完整切片:

>>> arr = [1, 2, 3]
>>> index = 1
>>> arr[:-index if index else None]
[1, 2]
>>> index = 0
>>> arr[:-index if index else None]
[1, 2, 3]

我的测试:

import timeit

def jonrsharpe(seq, index):
    return seq[:-index if index else None]

def Cyber(seq, index):
    return seq[:len(arr) - index]

def shashank(seq, index):
    return seq[:-index or None]

if __name__ == '__main__':
    funcs = ('jonrsharpe', 'Cyber', 'shashank')
    arr = range(1000)
    setup = 'from __main__ import arr, {}'.format(', '.join(funcs))
    for func in funcs:
        print func
        for x in (0, 10, 100, 1000):
            print x,
            print timeit.timeit('{}(arr, {})'.format(func, x), setup=setup)

和结果:

jonrsharpe
0 2.9769377505
10 3.10071766781
100 2.83629358793
1000 0.252808797871
Cyber
0 3.11828875501
10 3.10177615276
100 2.82515282642
1000 0.283648679403
shashank
0 2.99515364824
10 3.11204965989
100 2.85491723351
1000 0.201558213116

答案 3 :(得分:1)

由于在我选择最佳答案之前我无法入睡,因此除了@jonrsharpe提供的脚本之外,我还使用两个不同的脚本测试了每个答案的性能。

这是我用来比较使用profile的三种不同解决方案之间的性能的代码:

import profile

arr='test 123456789014'

def jonrsharpe(index):
    global arr
    for c in range(1,100000,1):
        a=arr[:-index if index else None]

def Cyber(index):
    global arr
    for c in range(1,100000,1):
        a=arr[:len(arr)-index]

def shashank(index):
    global arr
    for c in range(1,100000,1):
        a=arr[:-index or None]

def testf():
    for index in (0,3,6,9):
        jonrsharpe(index)
        Cyber(index)
        shashank(index)

if __name__ == '__main__':
    profile.run("testf()")

这是输出:

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
799992    1.629    0.000    1.629    0.000 :0(len)
   12    0.021    0.002    0.021    0.002 :0(range)
    1    0.006    0.006    0.006    0.006 :0(setprofile)
    1    0.000    0.000    4.390    4.390 <string>:1(<module>)
    0    0.000             0.000          profile:0(profiler)
    1    0.000    0.000    4.396    4.396 profile:0(testf())
    4    2.114    0.529    3.750    0.937 test.py:12(Cyber)
    4    0.307    0.077    0.313    0.078 test.py:19(shashank)
    1    0.000    0.000    4.390    4.390 test.py:26(testf)
    4    0.319    0.080    0.328    0.082 test.py:5(jonrsharpe)

另一种方法:

import time

if __name__ == '__main__':
    arr = '01234567890123456789012345678901234567890123456789'#range(1000)
    for x in (0, 10, 20, 30,40,49):
        print 'index=',x
        start=time.clock()
        for count in range(1000000):
            a=arr[:-x if x else None]

        print 'jonrsharpe=',round(time.clock()-start,4)

        start=time.clock()
        for count in range(1000000):
            a=arr[:len(arr)-x]
        print 'Cyber     =',round(time.clock()-start,4)

        start=time.clock()
        for count in range(1000000):
            a=arr[:-x or None]
        print 'shashank  =',round(time.clock()-start,4)

输出:

index= 0
jonrsharpe= 0.4918
Cyber     = 0.5341
shashank  = 0.4269
index= 10
jonrsharpe= 0.4617
Cyber     = 0.5334
shashank  = 0.4105
index= 20
jonrsharpe= 0.4271
Cyber     = 0.4562
shashank  = 0.3493
index= 30
jonrsharpe= 0.4217
Cyber     = 0.4548
shashank  = 0.3264
index= 40
jonrsharpe= 0.4713
Cyber     = 0.8488
shashank  = 0.6458
index= 49
jonrsharpe= 0.6159
Cyber     = 0.5663
shashank  = 0.4312

由于我将使用这行代码几十倍,性能非常重要,@ Shashank的解决方案在大多数情况下都是胜利者,即使它只是一点点。