파이썬에서 for 루프의 첫 번째 항목을 건너 뛰시겠습니까?


187

파이썬에서는 다음과 같은 것을 어떻게합니까?

for car in cars:
   # Skip first and last, do work for rest

4
나는 초보자이지만 사용하고 for n, i in enumerate(cars): if n!= 0: do something to i있습니다. 논리는 각 값에 '카운터'를 추가하여 예를 들어로 타겟팅 할 수 있다는 것입니다 if n == some_value. 이 예제에서는 첫 번째 인스턴스를 제외하고 i의 각 인스턴스에 무언가를 수행합니다.
user1063287

답변:


268

다른 답변은 시퀀스에서만 작동합니다.

반복 가능한 경우 첫 번째 항목을 건너 뛰십시오.

itercars = iter(cars)
next(itercars)
for car in itercars:
    # do work

마지막을 건너 뛰려면 다음을 수행하십시오.

itercars = iter(cars)
# add 'next(itercars)' here if you also want to skip the first
prev = next(itercars)
for car in itercars:
    # do work on 'prev' not 'car'
    # at end of loop:
    prev = car
# now you can do whatever you want to do to the last one on 'prev'

1
또한 참조 스벤 Marnach대답을
AGF

2
cars.pop (0) 및 cars.pop ()을 수행하는 것이 잘 작동한다는 것을 알았습니다.
dreamwork801

@ dreamwork801 첫 번째 의견에 링크 된 내 대답과 Sven은 반복이 시작되기 전에 데이터에 대해 O (n) 연산이 필요하지 않으므로 반복 가능하고 무한한 것에서도 작동합니다. 귀하의 제안과 Abhjit은 모두 반복 가능하지 않은 시퀀스에만 작동합니다.
agf

356

파이썬에서 첫 번째 요소를 건너 뛰려면 간단히 쓸 수 있습니다.

for car in cars[1:]:
    # Do What Ever you want

또는 마지막 요소를 건너 뛰려면

for car in cars[:-1]:
    # Do What Ever you want

이 개념을 모든 시퀀스에 사용할 수 있습니다.


52
모든 iterables 가 아니라 모든 시퀀스 에 적용 됩니다 .
Sven Marnach

2
메모리 사용량은 어떻습니까? slice가 새로운 서브 시퀀스 사본을 생성합니까?
보이저

@Voyager 예, 새 사본을 만듭니다.
Srinivas Reddy Thatiparthy

27

첫 번째 항목을 건너 뛰는 가장 좋은 방법은 다음과 같습니다.

from itertools import islice
for car in islice(cars, 1, None):
    # do something

이 경우 islice는 반복기의 끝을 나타내는 시작점 1과 끝점 없음으로 호출됩니다.

iterable의 끝에서 항목을 건너 뛸 수 있으려면 길이를 알아야합니다 (항상 목록에 대해서는 가능하지만 반복 할 수있는 모든 것은 아님). 예를 들어 islice (cars, 1, len (cars) -1)는 자동차 목록의 첫 번째 항목과 마지막 항목을 건너 뜁니다.


Sven의 (평가 부족) 답변을 살펴보십시오. 그는 islice길이를 알거나 절대적으로 필요한 것보다 더 많은 항목을 메모리에 저장하지 않고 반복 사용의 시작 및 / 또는 끝에서 임의의 수의 항목을 건너 뛰는 것을 다룹니다 .
agf

Sven의 답변은 실제로 전체 반복자를 메모리에 저장합니다. collections.deque는 반복자를 통해 실행됩니다. collections.deque (xrange (10000000))와 같은 것을 시도하십시오. 첫 번째 항목을 건너 뛰려면 모든 int를 메모리에 저장할 필요가 없습니다 ...
Roee Shenberg

2
islice에 전달되는 것입니다 deque아닌 전체 반복자, 그리고 마지막에 건너 뛸 항목의 수의 길이입니다. 전체 반복자를 메모리에 저장하지 않습니다.
agf

26

다음은 iterable의 시작과 끝에서 여러 항목을 건너 뛰는 일반적인 생성기 함수입니다.

def skip(iterable, at_start=0, at_end=0):
    it = iter(iterable)
    for x in itertools.islice(it, at_start):
        pass
    queue = collections.deque(itertools.islice(it, at_end))
    for x in it:
        queue.append(x)
        yield queue.popleft()

사용법 예 :

>>> list(skip(range(10), at_start=2, at_end=2))
[2, 3, 4, 5, 6, 7]

에 대한 빠른 경로를 추가하고 싶을 수도 있습니다 at_end == 0.
agf

collections.deque (...)는 즉시 반복자를 통과합니다. 즉, skip (xrange (10000000), 1)은 실제로는 안되지만 메모리를 많이 차지합니다.
Roee Shenberg

4
@RoeeShenberg : skip(xrange(10000000), 1)는을 사용 at_end=0하므로 매개 변수 deque()islice(it, 0)입니다 it. 이것은 많은 메모리를 차지하지 않습니다.
Sven Marnach

8
for item in do_not_use_list_as_a_name[1:-1]:
    #...do whatever

3
list변수 이름으로 사용하지 마십시오
Abhijit

OP는 첫 번째 요소 만 건너 뛰려고합니다. 왜 : -1?
luke14free

6
실제로 예약되어 있지 않습니다 . 이름 list은 리 바인드 될 수 있습니다. 그렇기 때문에 사용할 수없는 것이 아니라 사용 해서는 안됩니다 .
jscs

@ luke14free의 질문은 첫 번째 요소 건너 뛰기라고하지만 그의 코드 주석은 실제로 첫 번째와 마지막을 건너 뛰기를 원한다는 것을 암시합니다.
JerseyMike

@ luke14free 제목에 코드에 입력 한 내용이 아니라 제목이 표시됩니다. "처음 또는 마지막으로 건너 뛰기"
KurzedMetal

3

@SvenMarnach의 답변을 기반으로하지만 조금 더 간단하고 deque를 사용하지 않습니다.

>>> def skip(iterable, at_start=0, at_end=0):
    it = iter(iterable)
    it = itertools.islice(it, at_start, None)
    it, it1 = itertools.tee(it)
    it1 = itertools.islice(it1, at_end, None)
    return (next(it) for _ in it1)

>>> list(skip(range(10), at_start=2, at_end=2))
[2, 3, 4, 5, 6, 7]
>>> list(skip(range(10), at_start=2, at_end=5))
[2, 3, 4]

또한 내 timeit결과에 따르면 이것은 deque 솔루션보다 약간 빠릅니다.

>>> iterable=xrange(1000)
>>> stmt1="""
def skip(iterable, at_start=0, at_end=0):
    it = iter(iterable)
    it = itertools.islice(it, at_start, None)
    it, it1 = itertools.tee(it)
    it1 = itertools.islice(it1, at_end, None)
    return (next(it) for _ in it1)
list(skip(iterable,2,2))
    """
>>> stmt2="""
def skip(iterable, at_start=0, at_end=0):
    it = iter(iterable)
    for x in itertools.islice(it, at_start):
        pass
    queue = collections.deque(itertools.islice(it, at_end))
    for x in it:
        queue.append(x)
        yield queue.popleft()
list(skip(iterable,2,2))
        """
>>> timeit.timeit(stmt = stmt1, setup='from __main__ import iterable, skip, itertools', number = 10000)
2.0313770640908047
>>> timeit.timeit(stmt = stmt2, setup='from __main__ import iterable, skip, itertools, collections', number = 10000)
2.9903135454296716

를 사용 tee()하면 생성기의 메모리에 여전히 전체 목록을 작성하고 있습니까? ( it1
You

3

예:

mylist=['one'.'two','three'.'four'.'five']
for i in mylist[1:]:
   print(i)

파이썬 인덱스는 0부터 시작하여 슬라이싱 연산자를 사용하여 반복 조작을 할 수 있습니다.

for i in range(1,-1):

2

글쎄, 구문은 실제로 파이썬이 아닙니다.

파이썬에서 반복은 컨테이너의 내용 (기술적으로 반복자 이상)이며 구문이 for item in container있습니다. 이 경우 컨테이너는 cars목록이지만 첫 번째 요소와 마지막 요소를 건너 뛰고 싶습니다. 즉 cars[1:-1], 파이썬 목록은 0부터 시작하며 음수는 끝에서 세고 :구문은 조각화합니다.

그래서 너는 원해

for c in cars[1:-1]:
    do something with c

4
이것은 반복 가능한 (예 : 생성기)에서는 작동하지 않으며 시퀀스에서만 작동합니다.
Roee Shenberg

2

다른 방법 :

for idx, car in enumerate(cars):
    # Skip first line.
    if not idx:
        continue
    # Skip last line.
    if idx + 1 == len(cars):
        continue
    # Real code here.
    print car

2

여기 내가 선호하는 선택이 있습니다. 루프에 많은 것을 추가 할 필요가 없으며 내장 도구 만 사용합니다.

에서 이동:

for item in my_items:
  do_something(item)

에:

for i, item in enumerate(my_items):
  if i == 0:
    continue
  do_something(item)


1

more_itertools프로젝트를 확장itertools.islice 부정적인 인덱스를 처리 할 수 있습니다.

import more_itertools as mit

iterable = 'ABCDEFGH'
list(mit.islice_extended(iterable, 1, -1))
# Out: ['B', 'C', 'D', 'E', 'F', 'G']

따라서 iterable의 첫 번째 항목과 마지막 항목 사이에 슬라이스 요소를 우아하게 적용 할 수 있습니다.

for car in mit.islice_extended(cars, 1, -1):
    # do something

0

해킹처럼 보이지만 매번 작동합니다.

ls_of_things = ['apple', 'car', 'truck', 'bike', 'banana']
first = 0
last = len(ls_of_things)
for items in ls_of_things:
    if first == 0
        first = first + 1
        pass
    elif first == last - 1:
        break
    else:
        do_stuff
        first = first + 1
        pass
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.