문자열이 목록에서 문자열 중 하나로 끝나는 지 확인하십시오.


220

다음 코드를 작성하는 pythonic 방법은 무엇입니까?

extensions = ['.mp3','.avi']
file_name = 'test.mp3'

for extension in extensions:
    if file_name.endswith(extension):
        #do stuff

for루프 의 명시 적 선언을 피하고 if조건 에서 작성할 수 있다는 모호한 기억이 있습니다. 이것이 사실입니까?


2
이 질문에 잘 대답되지만, 아마도 저자는 원래 생각 if any((file_name.endswith(ext) for ext in extensions)).
sapht

답변:


450

str.endswith 는 널리 알려져 있지는 않지만 튜플도 허용합니다. 반복 할 필요가 없습니다.

>>> 'test.mp3'.endswith(('.mp3', '.avi'))
True

10
왜 목록을 수락하지 않지만 튜플을 수행하는지 알고 있습니까? 그냥 궁금
ilyail3

2
@falsetru 답변의 링크가 해당 질문에 명시 적으로 답변하지 않습니다. 그것은 튜플 수락 할 있지만 목록을 수락 할 수없는 이유 는 언급 하지 않습니다 . 둘 다 시퀀스이기 때문에 잠재적으로 볼 수있는 유일한 차이점은 목록은 변경 가능하지만 튜플은 변경할 수 없다는 것입니다. 나는 틀렸을 수도 있지만, 그것이 명시 적으로 언급 된 다른 이유는 볼 수 없습니다.
KymikoLoco

4
문자열이 문자로 끝나는 지 확인하려면import string; str.endswith(tuple(string.ascii_lowercase))
Alex Willison

3
참고로, endswith파이썬 2.5 이상에서만 튜플을 허용합니다
Akash Singh

1
이것을 몰랐다! 저건 완벽 해!
fool4jesus


6

파일에서 확장자를 가져 와서 확장자 세트에 있는지 확인하십시오.

>>> import os
>>> extensions = set(['.mp3','.avi'])
>>> file_name = 'test.mp3'
>>> extension = os.path.splitext(file_name)[1]
>>> extension in extensions
True

세트에서 조회의 시간 복잡성이 O (1) ( docs ) 이므로 세트를 사용합니다 .


8
그냥 참고로 당신은 상당히 짧은 튜플에 대한 효율성을 언급로 .endswith()구금 튜플로 빠르게 세트 조회보다 것이다
존 클레멘트

@JonClements 나는 당신이 답변과 질문에 멋진 메모를하기 위해 특별한 SO 금 코멘트 배지가 필요하다고 생각합니다 :)
alecxe

아냐-난 그냥 "Stalking alecxe"배지로 갈거야;)
Jon Clements

2
또한 2.7 이상에서는 집합에 대한 수학 구문을 {'.mp3','.avi'}사용할 수 있으며 추가 유형 변환을 피하고 배경에 따라 더 읽기 쉽습니다 ( '사전과 혼동을 일으킬 수 있지만 빈을 만드는 데 사용할 수는 없지만) 세트).
퍼킨스

@JonClements 언젠가 나는 당신만큼 현명 해 질 것입니다 :)
alecxe

3

정규식과 문자열 (str) 메소드의 두 가지 방법이 있습니다.

문자열 메소드는 일반적으로 더 빠릅니다 (~ 2x).

import re, timeit
p = re.compile('.*(.mp3|.avi)$', re.IGNORECASE)
file_name = 'test.mp3'
print(bool(t.match(file_name))
%timeit bool(t.match(file_name)

루프 당 792ns ± 1.83ns (평균 ± 표준 7 회 실행, 각각 1000000 루프)

file_name = 'test.mp3'
extensions = ('.mp3','.avi')
print(file_name.lower().endswith(extensions))
%timeit file_name.lower().endswith(extensions)

루프 당 274ns ± 4.22ns (평균 7 번의 평균 ± 표준 편차, 각각 1000000 루프)


1

나는 이것을 가지고있다:

def has_extension(filename, extension):

    ext = "." + extension
    if filename.endswith(ext):
        return True
    else:
        return False

1
당신은 의미 return filename.endswith(ext)합니까? : P
Mr_and_Mrs_D 17 년

1

나는 다른 것을 찾는 동안 방금 이것을 만났습니다.

os패키지 의 메소드를 사용하는 것이 좋습니다 . 이상한 경우를 보완하여 더 일반적으로 만들 수 있기 때문입니다.

당신은 다음과 같은 것을 할 수 있습니다 :

import os

the_file = 'aaaa/bbbb/ccc.ddd'

extensions_list = ['ddd', 'eee', 'fff']

if os.path.splitext(the_file)[-1] in extensions_list:
    # Do your thing.

0

또 다른 가능성은 IN 문을 사용하는 것입니다.

extensions = ['.mp3','.avi']
file_name  = 'test.mp3'
if "." in file_name and file_name[file_name.rindex("."):] in extensions:
    print(True)

그런 경우에는 @ Rainald62 index여야합니다 rindex.
NeverHopeless

0

일치하는 문자열 목록을 반환 할 수있는 다른 방법은

sample = "alexis has the control"
matched_strings = filter(sample.endswith, ["trol", "ol", "troll"])
print matched_strings
['trol', 'ol']
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.