2013-10-08 3 views
2

범위 기반 선택의 보완을 처리하는 파이썬 "코어"구문이 있는지 궁금합니다.Python - 범위 기반 하위 목록 선택의 보완

offset = 1 
step = 3 
a[offset::step] = [1,4]. 

내 질문은 따라서이다, 예를 들어, 그

a = [0,1,2,3,4,5,6] 

말 :

"나는 ifs를 사용하지 않고

a[~(offset::step)] == [0,2,3,5,6] 

처럼 할 수 ? "

또는 "가장 큰 것은 pythonic 처리 방법은 무엇입니까?"

부록 :

제가리스트 수천이 서브 샘플링 동작 가변 크기 (실제로 입자의 궤적) (가변 시간 길이, 즉 궤적)을 할 필요가 있음을 말한다. 따라서 정확한 인덱스 세트를 미리 계산할 수는 없습니다.

답변

2

세트는 시간에 앞서 인덱스를 채울 수없는 경우에도, 빨리 크기 순서에 대해 (보통)이다 : 나는 전체 인덱스를 계산하고 있지 않다 xrange``를 통해 있도록

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 
2

색인을 생성 한 다음 목록 이해를 사용하여 해당 색인과 일치하지 않는 모든 값을 선택해야합니다. (파이썬 2 xrange())를 인덱스를 테스트하기위한 효율적인 방법에 대한 range() 객체를 사용

indices = range(offset, len(a), step) 
[v for i, v in enumerate(a) if i not in indices] 

(파이썬 2 xrange()) 파이썬 3의 range() 객체 만이 in을 시작, 끝, 및 스텝 값을 보유 테스트 된 값이 범위의 일부인 경우 테스트는 간단히 빠른 계산을 수행합니다.

데모 :

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

예,이 여전히 if 문을 사용하여 필요하지만 테스트가 저렴하고 필요에 따라 발전기 표현에 통합 할 수 있습니다 여전히를

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

내가 참조 세트. 이것은 아마도 더 빠를 것입니다. – Acorbe

+0

@Acorbe :'xrange()'멤버십 테스트는 일정한 비용을 가지고 있습니다. 그렇습니다. –

0

사용하는 동안 다음은 필요한 대답을 제공한다고 믿는 단일 단계 목록 이해력입니다 :

>>> 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보다 범위 구조를 사용하는 것보다 효과적인지 또는 덜 효율적인지는 잘 모르겠습니다.