Python-基于范围的子列表选择的补充

Python-基于范围的子列表选择的补充,python,list,range,Python,List,Range,我想知道是否有python“核心”语法来处理基于范围的选择的补充 说 a = [0,1,2,3,4,5,6] 那么比如说, offset = 1 step = 3 a[offset::step] = [1,4]. 因此,我的问题是: “我能喜欢吗 a[~(offset::step)] == [0,2,3,5,6] 不使用ifs?” 或者,“什么是处理这个问题的最适合的方法?” 附录: 假设我必须对数千个大小可变的列表(即可变时间长度的轨迹)执行此子采样操作。因此,我无法预先计算正

我想知道是否有python“核心”语法来处理基于范围的选择的补充

 a = [0,1,2,3,4,5,6]
那么比如说,

 offset = 1
 step = 3
 a[offset::step] = [1,4].
因此,我的问题是:

“我能喜欢吗

 a[~(offset::step)] == [0,2,3,5,6]
不使用
ifs
?”

或者,“什么是处理这个问题的最适合的方法?”

附录:


假设我必须对数千个大小可变的列表(即可变时间长度的轨迹)执行此子采样操作。因此,我无法预先计算正确的索引集。

您必须生成索引,然后使用列表理解来选择所有与这些索引不匹配的值。使用
range()

Python3中的
range()
对象(Python2中的
xrange()
对象)仅保存开始、结束和步骤值,
测试中的
如果测试值是范围的一部分,则只需进行快速计算

演示:

是的,这仍然需要使用
if
语句,但测试成本很低,可以根据需要合并到生成器表达式中:

for i in (v for i, v in enumerate(a) if i not in range(offset, len(a), step)):

您必须生成索引,然后使用列表理解来选择所有与这些索引不匹配的值。使用
range()

Python3中的
range()
对象(Python2中的
xrange()
对象)仅保存开始、结束和步骤值,
测试中的
如果测试值是范围的一部分,则只需进行快速计算

演示:

是的,这仍然需要使用
if
语句,但测试成本很低,可以根据需要合并到生成器表达式中:

for i in (v for i, v in enumerate(a) if i not in range(offset, len(a), step)):

在仍然使用if的情况下,我相信以下是一个单步列表理解,可以为您提供所需的答案:

>>> offset = 1
>>> step = 3
>>> a = [0,1,2,3,4,5,6]
>>> [v for i, v in enumerate(a) if not i%step == offset]
[0, 2, 3, 5, 6]
>>>

我不知道的是,这是否比在mod上使用range构造更有效。

在仍然使用if的情况下,下面是一个单步列表理解,我相信它可以为您提供所需的答案:

>>> offset = 1
>>> step = 3
>>> a = [0,1,2,3,4,5,6]
>>> [v for i, v in enumerate(a) if not i%step == offset]
[0, 2, 3, 5, 6]
>>>
我不知道的是,这是否比在mod上使用范围构造更有效。

集合(通常)大约快一个数量级,即使您没有提前填充索引:

r100 = range(100)
r2 = range(3, 40, 3)

# Find indices in r100 that aren't in r2.
# This is a set difference (or symmetric difference)
## Set methods
# Precalculated is fastest:
sr100 = set(r100)
sr2 = set(r2)
%timeit sr100 - sr2
100000 loops, best of 3: 3.84 us per loop

# Non-precalculated is still faster:
%timeit set(range(100)) ^ set(range(3,40,3))
100000 loops, best of 3: 9.76 us per loop
%timeit set(xrange(100)) ^ set(xrange(3,40,3))
100000 loops, best of 3: 8.84 us per loop

# Precalculating the original indices still helps, if you can hold it in memory:
%timeit sr100 ^ set(xrange(3,40,3))
100000 loops, best of 3: 4.87 us per loop

# This is true even including converting back to list, and sorting (if necessary):
%timeit [x for x in sr100 ^ set(xrange(3,40,3))]
100000 loops, best of 3: 9.02 us per loop
%timeit sorted(x for x in sr100 ^ set(xrange(3,40,3)))
100000 loops, best of 3: 15 us per loop


## List comprehension:

# Precalculated indices
%timeit [x for x in r100 if x not in r2]
10000 loops, best of 3: 30.5 us per loop

# Non-precalculated indices, using xrange
%timeit [x for x in xrange(100) if x not in xrange(3, 40, 3)]
10000 loops, best of 3: 65.8 us per loop

# The cost appears to be in the second xrange?
%timeit [x for x in r100 if x not in xrange(3, 40, 3)]
10000 loops, best of 3: 64.3 us per loop
%timeit [x for x in xrange(100) if x not in r2]
10000 loops, best of 3: 29.9 us per loop
# xrange is not really any faster than range here - uses less memory, but still have
# to walk through entire list
%timeit [x for x in range(100) if x not in range(3, 40, 3)]
10000 loops, best of 3: 63.5 us per loop
即使没有提前填充索引,集合(通常)也会快一个数量级:

r100 = range(100)
r2 = range(3, 40, 3)

# Find indices in r100 that aren't in r2.
# This is a set difference (or symmetric difference)
## Set methods
# Precalculated is fastest:
sr100 = set(r100)
sr2 = set(r2)
%timeit sr100 - sr2
100000 loops, best of 3: 3.84 us per loop

# Non-precalculated is still faster:
%timeit set(range(100)) ^ set(range(3,40,3))
100000 loops, best of 3: 9.76 us per loop
%timeit set(xrange(100)) ^ set(xrange(3,40,3))
100000 loops, best of 3: 8.84 us per loop

# Precalculating the original indices still helps, if you can hold it in memory:
%timeit sr100 ^ set(xrange(3,40,3))
100000 loops, best of 3: 4.87 us per loop

# This is true even including converting back to list, and sorting (if necessary):
%timeit [x for x in sr100 ^ set(xrange(3,40,3))]
100000 loops, best of 3: 9.02 us per loop
%timeit sorted(x for x in sr100 ^ set(xrange(3,40,3)))
100000 loops, best of 3: 15 us per loop


## List comprehension:

# Precalculated indices
%timeit [x for x in r100 if x not in r2]
10000 loops, best of 3: 30.5 us per loop

# Non-precalculated indices, using xrange
%timeit [x for x in xrange(100) if x not in xrange(3, 40, 3)]
10000 loops, best of 3: 65.8 us per loop

# The cost appears to be in the second xrange?
%timeit [x for x in r100 if x not in xrange(3, 40, 3)]
10000 loops, best of 3: 64.3 us per loop
%timeit [x for x in xrange(100) if x not in r2]
10000 loops, best of 3: 29.9 us per loop
# xrange is not really any faster than range here - uses less memory, but still have
# to walk through entire list
%timeit [x for x in range(100) if x not in range(3, 40, 3)]
10000 loops, best of 3: 63.5 us per loop

我明白了,所以通过
xrange
我没有计算整个索引集。这应该更快。@Acorbe:
xrange()
成员资格测试有固定成本,是的。我明白了,所以通过
xrange
我不会计算整个索引集。这应该更快。@Acorbe:
xrange()
成员资格测试的成本是固定的,是的。