2013-07-09 5 views
2

편의상 여러 값에 대해 단일 값, 목록 또는 반복기 중 하나의 함수를 전달하고 싶습니다. 하나의 루프에서 세 가지 변형을 모두 수용 할 수 있도록 단일 항목에서 반복자를 생성하는 방법이 이상적입니다.하나 또는 여러 항목을 반복하는 방법은 무엇입니까?

from collections import Iterable 

def iterate(seq_or_single): 
    if isinstance(seq_or_single, Iterable) and not isinstance(seq_or_single, basestring): 
     return seq_or_single 
    return [seq_or_single] 

# for x in iterate(param): 
당신이 do_something이 형식 오류를 던지고 대해 걱정하는 경우
+2

당신이 PARAM이 문자열 인 경우 일어날 것으로 예상합니까? –

+0

@gnibbler, 하! 좋은 질문 - 내 특정 사용 사례에 대한 문자열을 단일 매개 변수로 간주하고 싶습니다. 하지만 반복 가능한 문자 시퀀스로 취급하는 답변에 대해서는 열려 있습니다. –

+0

그러한 기능을 구현하는 것이 좋은지 여부는 의문입니다. – zhangyangyu

답변

3
def flexible_func(param): 
    try: 
     # If it's any kind of iterable, you can iterate over it 
     for x in mystery_wrapper(param): 
      do_something(x) 
    except TypeError: 
     # Not iterable, so it's a single item 
     do_something(param) 

, 당신은 혼자 iter(param)

def flexible_func(param): 
    try: 
     iterable = iter(param) 
    except TypeError: 
     iterable = [param] 
    for x in iterable: 
     do_something(x) 

으로 테스트 할 수 있습니다 : 여기

def flexible_func(param): 
    for x in mystery_wrapper(param): 
     do_something(x) 

flexible_func('single') 
flexible_func(['one', 'two']) 
flexible_func(generator) 


내가 마지막에 무슨 일이 있었는지입니다 데코레이터 버전

def mystery(func): 
    def inner(arg): 
     try: 
      return func(iter(arg)) 
     except TypeError: 
      return func([arg]) 
    return inner 

@mystery 
def flexible_func(param): 
    for x in param: 
     do_something(x) 
+1

+ 그것의 속임수,하지만 이런 식으로 코드를 작성하는 것이 바람직합니까 ?? 인수의 유형을 확인하고 파이썬에서 조건부 코드를 실행할 수 있습니까? –

+0

'flexible_func'보다는'mystery_wrapper'에 대한 해결책을보고 싶습니다. 더 재사용 할 수 있습니다. –

+0

@ MarkRansom,'mystery_wrapper' 데코레이터는 괜찮습니까? –

2

이와 비슷한 제품을 찾고 계십니까? 또 다른 방법

def wrapper(arg): 
     try: 
      for ar in arg: 
       yield ar 
     except: 
      yield arg 

다음

for x in wrapper(range(1,5)): 
    print x 

또는

다음
for x in wrapper(1): 
    print x 
+0

네, 그게 내가 원하는 것입니다. 이런 일이 이미 itertools에 내장되어 있기를 바랬습니다. –

1

로 사용할 수 있습니다 :

import collections 

def flexible_func(*param): 
    li=[] 
    for x in param: 
     if isinstance(x,collections.Iterable): 
      for y in x: 
       li.append(y) 
     else: 
      li.append(x) 
    do_something(li) 

def do_something(li): 
    for x in li: 
     print x 

if __name__ == '__main__': 
    flexible_func('single') 
    flexible_func(['one', 'two']) 
    flexible_func(range(6)) 
관련 문제