在python中一次跳过列表的特定范围

use*_*847 5 python numpy python-xarray

我有一个数组,我想选择前 2 个或范围,跳过下一个 2,选择下一个 2,然后继续直到列表末尾

list = [2, 4, 6, 7, 9,10, 13, 11, 12,2]
results_wanted = [2,4,9,10,12,2] # note how it skipping 2. 2 is used here as and example
Run Code Online (Sandbox Code Playgroud)

有没有办法在Python中实现这一点?

Kel*_*ndy 7

from itertools import compress, cycle\n\nresults = list(compress(lst, cycle([1,1,0,0])))\n
Run Code Online (Sandbox Code Playgroud)\n

或者

\n
results = [x for i, x in enumerate(lst) if i % 4 < 2]\n
Run Code Online (Sandbox Code Playgroud)\n

或者,如果您不再需要原始列表,则可以修改它而不是构建新列表(如果您确实想要一个新列表,您仍然可以在副本上使用它):

\n
del lst[2::4], lst[2::3]\n
Run Code Online (Sandbox Code Playgroud)\n

具有一百万个元素的列表的基准:

\n
  8.6 ms \xc2\xb1 0.1 ms _del_slices\n 11.6 ms \xc2\xb1 0.1 ms _compress_bools\n 13.6 ms \xc2\xb1 0.0 ms _compress_ints\n 14.1 ms \xc2\xb1 0.0 ms _copy_del_slices\n 22.6 ms \xc2\xb1 0.2 ms _copy_slices\n 46.0 ms \xc2\xb1 0.2 ms Black_Raven\n 59.5 ms \xc2\xb1 0.4 ms Vikrant_Sharma\n 84.8 ms \xc2\xb1 0.1 ms _enumerate_modulo\n161.8 ms \xc2\xb1 0.6 ms RCvaram\n
Run Code Online (Sandbox Code Playgroud)\n

不包括 numpy 解决方案,因为我必须为此切换到较旧的 Python 版本,并且比较没有意义(np.array(lst)已经花费了约 55 毫秒)。

\n

基准代码(在线尝试!):

\n
def _compress_ints(lst):\n    return list(compress(lst, cycle([1,1,0,0])))\n\ndef _compress_bools(lst):\n    return list(compress(\n        lst,\n        cycle(chain(repeat(True, 2),\n                    repeat(False, 2)))\n    ))\n\ndef _enumerate_modulo(lst):\n    return [x for i, x in enumerate(lst) if i % 4 < 2]\n\ndef _del_slices(lst):\n    del lst[2::4], lst[2::3]\n    return lst\n\ndef _copy_del_slices(lst):\n    results = lst[:]\n    del results[2::4], results[2::3]\n    return results\n\ndef _copy_slices(lst):\n    a = lst[::4]\n    b = lst[1::4]\n    results = [None] * (len(a) + len(b))\n    results[::2] = a\n    results[1::2] = b\n    return results\n    \ndef Black_Raven(list1):\n    add = skip = 2\n    list2 = []\n    for i in range(0, len(list1), skip+add):\n        list2 += list1[i:i+add]\n    return list2\n\ndef Vikrant_Sharma(l):\n    n = 2\n    return [x for i in range(0, len(l), n + n) for x in l[i: i + n]]\n\ndef RCvaram(test):\n        skip = 2\n        desireList = []\n        skipMode = False\n        for i in range(0,len(test)):\n            if skipMode==False:\n                desireList.append(test[i])\n            if (i+1)%skip==0:\n                skipMode=not skipMode\n        return desireList\n\nfuncs = [_compress_ints, _compress_bools, _enumerate_modulo, _del_slices, _copy_del_slices, _copy_slices, Black_Raven, Vikrant_Sharma, RCvaram]\n\nfrom timeit import default_timer as timer\nfrom itertools import compress, cycle, repeat, chain, islice\nfrom random import shuffle\nfrom statistics import mean, stdev\nimport gc\n\n# Correctness\nlst = [2, 4, 6, 7, 9,10, 13, 11, 12,2]\nresults_wanted = [2,4,9,10,12,2]\nfor func in funcs:\n    assert func(lst[:]) == results_wanted\nfor n in range(100):\n    lst = list(range(n))\n    expect = funcs[0](lst[:])\n    for func in funcs:\n        assert func(lst[:]) == expect, func.__name__\n\n# Speed\ntimes = {func: [] for func in funcs}\ndef stats(func):\n    ts = [t * 1e3 for t in sorted(times[func])[:3]]\n    return f\'{mean(ts):5.1f} ms \xc2\xb1 {stdev(ts):.1f} ms\'\noriginal = list(range(1000000))\nfor _ in range(15):\n    shuffle(funcs)\n    for func in funcs:\n        lst = original.copy()\n        gc.collect()\n        t0 = timer()\n        result = func(lst)\n        t = timer() - t0\n        del result\n        times[func].append(t)\nfor func in sorted(funcs, key=stats):\n    print(stats(func), func.__name__)\n
Run Code Online (Sandbox Code Playgroud)\n


小智 4

获取n元素数量并跳过下一个n

l = [2, 4, 6, 7, 9, 10, 13, 11, 12, 2]
n = 2
wanted = [x for i in range(0, len(l), n + n) for x in l[i: i + n]]
### Output : [2, 4, 9, 10, 12, 2]
Run Code Online (Sandbox Code Playgroud)