변수가리스트인지 터플인지 테스트


234

파이썬에서 변수에 목록이나 튜플이 있는지 테스트하는 가장 좋은 방법은 무엇입니까? (즉, 컬렉션)

isinstance()여기에 제안 악? http://www.canonical.org/~kragen/isinstance/

업데이트 : 목록과 문자열을 구별하려는 가장 일반적인 이유는 무한한 중첩 트리 / 문자열 목록 목록의 데이터 구조 등이 있는데 재귀 알고리즘으로 탐색하고 필요합니다. "리프"노드에 도달했을 때 알 수 있습니다.


72
유형 검사를 악으로 광범위하게 무시하는 것은 약간 쉬운 일입니다. 언어의 일부입니다. 너무 악한 경우 누군가 PEP를 작성하여 제거해야합니다.
Adam Crossland

4
@Adam Crossland : "언어의 일부입니다." 0으로 나누는 것과 같습니다. 피할 수 있습니다. 이 경우 추가 정보가 없으면 아마도 완전히 필요하지 않을 것입니다. 파이썬에서 대부분의 타입 검사는 불필요합니다. 모든 것이 불필요 하기 때문에 일부 유형 검사가 필요합니다. 그렇다고해서 그것이 도움이되고, 가치 있거나, 좋은 아이디어라는 의미는 아닙니다.
S.Lott

11
따라서 일부 유형 검사가 필요하지만 그럼에도 불구하고 쓸모없고 쓸모가 없으며 나쁜 생각입니다. 미안하지만 이해가되지 않습니다.
Glenn Maynard 님

18
"XXX는 악하다"는 잘못 생각하여 "XXX를 요구하는 방식이 실제로 사용되어야 할 시점을 이해하지 못하고 거의 확실하게 다른 것을 원한다는 것을 암시하는"오해의 소지가 있습니다. 그럴 가능성이 높습니다.
Glenn Maynard 님

2
나는 그것을 악으로 널리 무시하지 않았습니다. 나는 그것이 악한시기와 정당한시기에 관한 짧은 에세이를 썼습니다. 이 에세이는 옳고 그름이 분명하고 모호하고 즐겁고 지루한 많은 것들 일 수 있지만 그 중 하나는 기술의 광범위한 해고입니다.
Kragen Javier Sitaker

답변:


101

isinstance필요한 경우 계속 사용 하십시오. 커스텀 시퀀스, 반복자 및 실제로 필요한 다른 것들을 배제하기 때문에 다소 악합니다. 그러나 누군가가 예를 들어 문자열을 전달하는 경우 때때로 다르게 행동해야합니다. 내 선호는 명시 적으로 확인 str하거나 unicode좋아하는 것입니다.

import types
isinstance(var, types.StringTypes)

NB 마 혼동하지 types.StringType위해 types.StringTypes. 후자는 통합 str하고 unicode반대한다.

types모듈은 오히려 위를 사용하지 않는 게 좋을 그래서 만약 당신이 다른 방법에 대해 명시 적으로 확인할 수 있습니다, 단지 객체의 유형에 대해 직접 확인 찬성 쓸모 많은 것에 의해 간주 str하고 unicode다음과 같이 :

isinstance(var, (str, unicode)):

편집하다:

더 나은 방법은 다음과 같습니다.

isinstance(var, basestring)

편집 종료

이 중 하나를 마치면 정상적인 시퀀스를 얻는 것처럼 동작하여 비 시퀀스가 ​​적절한 예외를 발생시킬 수 있습니다.

유형 검사에 대해 "악한"것은 특정 유형의 객체에 대해 다르게 행동하기를 원치 않는 것이 아니라, 예상치 못한 객체 유형으로 올바른 행동을 수행하지 못하도록 인위적으로 기능을 제한하는 것입니다. 유형 확인되지 않은 최종 폴 백이 있으면이 제한을 제거합니다. 너무 많은 유형 검사는 리팩토링을 원할 수도 있음을 나타내는 코드 냄새이지만 반드시 getgo에서 피해야한다는 것을 의미하지는 않습니다.


2
types 모듈은 약간의 역사적 이슈입니다. docs.python.org/dev/library/types.html#module-types에서 언급했듯이 실제로 str유형을 확인 해야하는 경우 types.StringType별칭을 사용 하는 대신 직접 사용해야 합니다. 그러나 나는이 답변이 "컬렉션"에 관한 것이기 때문에 질문에 대답하지 않는다고 생각합니다. 확인할 수있는 abc모듈이 아닌 새로운 파이썬을 사용하지 않는 한 isinstance, 가능하다면 검사를 피하는 것이 좋습니다.
mzz

1
assert isinstance(u'abc', str) == False. types모듈을 사용하는 대신 유형을 직접 확인하는 것이 좋지만 types.StringTypes그렇지 않은 작업은 str수행 합니다. True for strunicodeobjects를 반환 합니다. 대안으로 이중 확인을 제공하기 위해 응답을 편집하겠습니다.
jcdyer

1
컬렉션을 직접 확인하는 질문에 직접 답변하지 않았지만 실제 질문은 " isinstance악?" 그리고 나는 (1)의 악의가 아닌 사용이라는 반대의 예를 isinstance들었습니다. 무언가는 list또는 tuple(즉, 문자열에서 명확하게하기 위해)입니다.
jcdyer

필자는 종종 사용자 정의 유형이 문자열처럼 작동하는 것이 유용하다는 경고에 동의합니다. 그러나 파이썬의 OO는 지금까지만 진행되었습니다 ...
Kragen Javier Sitaker

합니까는 class Foo(str): pass당신이 원하는 무엇입니까?
jcdyer

567
if type(x) is list:
    print 'a list'
elif type(x) is tuple:
    print 'a tuple'
else:
    print 'neither a tuple or a list'

1
작동하지 않는 것 같습니다 : type ([]) ==> list; type ([])은 list ===> False
sten

3
파이썬에서 2.7.5 : type([]) is list리턴True
데이비드 가이거

54
type(x) in [list,tuple]더 짧습니다.
Alex Holcombe

x와 type (x)
Kenichi Shibata

나는 너무 많이 스크롤을 내려야했다. : D
Rithwik

38

isinstance중복되지 않는 한 사용 하는 데 아무런 문제가 없습니다. 변수가 목록 / 튜플 일뿐이라면 인터페이스를 문서화하고 그대로 사용하십시오. 그렇지 않으면 수표는 완벽하게 합리적입니다.

if isinstance(a, collections.Iterable):
    # use as a container
else:
    # not a container!

이 유형의 검사에는 표준 문자열 startswith / endswith 메소드 와 같은 유용한 유스 케이스 가 있습니다 (정확하지만 튜플인지 확인하기 위해 명시 적 검사를 사용하여 CPython에서 C로 구현되지만 여러 가지 방법이 있습니다) 링크 된 기사에서 언급 했듯이이 문제를 해결하려면).

명시 적 검사는 종종 컨테이너로 객체를 사용하고 예외를 처리하는 것보다 낫습니다. 이로 인해 코드가 부분적으로 또는 불필요하게 실행되는 모든 종류의 문제가 발생할 수 있습니다.


15
변수가 반복 가능한지 확인하는 좋은 방법입니다. 그러나 아마도이 질문의 목적으로는 효과가 없을 것입니다. 문자열도 반복 가능하며 오 탐지가 발생할 수 있습니다.
Corey O.

set객체는, 반복 가능하다 당신은 분명히 그것에서 요소를 팝업 할 수 있지만, 동안 특정 알고리즘을위한 매우 위험한 일입니다 특정 순서를 보장하지 않는다는 것을 의미합니다. 요소의 순서가 중요 할 경우이 스 니펫을 사용하는 알고리즘이 다른 실행에서 다른 결과를 생성 할 수 있습니다!
koo


12

어때요 hasattr(a, "__iter__")?

반환 된 객체가 생성기로 반복 될 수 있는지 알려줍니다. 기본적으로 튜플과 목록은 문자열 유형이 아니라 문자열 유형이 될 수 있습니다.


나는 이것이 정말로 유용하다는 것을 알았다.
javadba

8
또한 문자열에 대해서는 True입니다 (적어도 Python 3에서는).
SzieberthAdam

2
이것은 잘못된 대답입니다. 'str'유형에는 ' iter ' 메소드 도 있습니다. @SzieberthAdam이 옳았습니다. 'set'유형도 반복 가능하지만 주문할 수는 없습니다.
PADYMKO

또한 dicts 있습니다 __iter__.
thet

계속하면, 사용자 정의 유형이있을 수 있습니다 __iter__... 어떤 이유
알렉산더 IRBIS

10

파이썬 2.8에서 type(list) is list반환 false
할 때이 끔찍한 방식으로 유형을 비교하는 것이 좋습니다.

if type(a) == type([]) :
  print "variable a is a list"

(적어도 내 시스템에서는 Mac OS X Yosemite에서 아나콘다를 사용함)


1
type (a) is list도 false로 평가됩니까?
Dmitriy Sintsov

4
Python 2.7.8을 의미 했습니까? python.org/dev/peps/pep-0404/#official-pronouncement
Carl

안녕하세요, 저는 궁금합니다 : 당신의 예가 왜 "끔찍한 것"이라고 생각하십니까?
세스 코넬

type(list) is list반환 False때문 type(list)입니다 type하지 list. type(list()) is list또는 목록의 다른 인스턴스 와 함께 반환 True됩니다.
Michael Greene

8

파이썬은 "오리 타이핑 (Duck typing)"을 사용합니다. 즉, 오리와 같은 변수가 오리라면 오리 여야합니다. 귀하의 경우 반복 가능하거나 특정 색인에서 항목에 액세스하려고 할 수 있습니다. 당신은 이것을해야합니다 : 즉 블록 내부 for var:또는 var[idx]내부 에서 객체를 사용하십시오 try. 예외가 발생하면 오리가 아닙니다 ...


7
이것에 대한 문제는 var아마도 문자열 예기치 않은 결과와 함께 문자열 반복이 발생한다는 것입니다.
Brian M. Hunt

Brian M. Hunt가 말한 사실에도 불구하고 그의 허락은 용서보다는 용서를 구한다는 측면에서 꽤 비현실적인 해결책입니다.
Géza Török


3

foo[123]변수와 함께 표기법을 사용할 수 있는지 알아야 할 경우 __getitem__속성 (인덱스로 액세스 할 때 파이썬이 호출하는 것)이 있는지 확인할 수 있습니다.hasattr(foo, '__getitem__')


2

함수 인수로 거의 모든 것을 처리하려면 더 복잡한 테스트가 필요합니다.

type(a) != type('') and hasattr(a, "__iter__")

비록 보통 함수가 iterable을 예상하고 체크 만한다는 것을 철자하는 것으로 충분합니다. type(a) != type('') .

또한 문자열의 경우 간단한 처리 경로가 있거나 멋지고 스플릿 등을 할 수 있으므로 문자열에서 소리를 지르고 싶지 않으며 누군가가 당신에게 이상한 것을 보내면 그냥 보내십시오. 예외.


2

변수가 목록인지 튜플인지 또는 일반적으로 변수 유형을 확인하는 쉬운 방법은 다음과 같습니다.

    def islist(obj):

        if ("list" in str(type(obj)) ): return True

        else : return False

1

원칙적으로 위의 Ignacio에 동의하지만 유형 을 사용 하여 무언가가 튜플인지 목록인지 확인할 수도 있습니다 .

>>> a = (1,)
>>> type(a)
(type 'tuple')
>>> a = [1]
>>> type(a)
(type 'list')
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.