2013-07-09 19 views
2

爲了方便起見,我想通過一個函數傳遞一個值,一個列表或一個遍歷多個值的迭代器。理想情況下,有一種方法可以從單個項目生成迭代器,以便一個循環可以容納所有三種變體。如何迭代單個或多個項目?

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

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


這是我最後用去:

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): 
+2

你能指望什麼發生,如果參數是一個字符串? –

+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) 

如果你擔心do_something拋出類型錯誤,你可以用iter(param)單獨

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

測試裝飾者版本

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

+它的一個竅門,但是最好是寫這樣的代碼?我們可以檢查參數的類型並在Python中運行條件代碼。 –

+0

我寧願看到'mystery_wrapper'而不是'flexible_func'的解決方案,它會更加可重用。 –

+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)) 
相關問題