无缝地处理可迭代和不可迭代的对象

时间:2014-09-17 15:43:28

标签: python iterator

如何使此函数独立于参数X和的可迭代性而没有任何if / else条件

我想象这个问题之前已经被问过/回答过但我找不到任何东西。

def do_something(X):
  return map(lambda x: x ,X)

# Possible input:

do_something([1,2,3]) #-> [1,2,3]
do_something(1) # -> [1]

修改

我希望将标量参数视为一维元素数组,例如1 - > [1],因此返回值应始终为列表。

Numpy解决方案:

刚才意识到numpy提供了这个功能:

import numpy

def do_something(X):
  return map(lambda x: x ,numpy.atleast_1d(X))

所以现在的问题是:"有没有办法在不导入numpy的情况下实现相同的目标"?

3 个答案:

答案 0 :(得分:2)

EAFP

def do_something(X):
    try:
       return map(lambda x: x, X)
    except TypeError:
       return map(lambda x: x, [X])

基本上,您尝试使用给定map的{​​{1}},如果失败,请再次尝试使用包含X的单元素列表。

请注意,如果您的功能可以引发X,则您需要以某种方式检查TypeError或其调用的函数是否引发了错误。这是可能的......使用map语句。

答案 1 :(得分:1)

您可以根据可以处理的项目来检查传递的项目是否可迭代:

>>> from collections import Iterable
def do_something(X):
    f = lambda x: x**2
    if isinstance(X, Iterable):
        return map(f, X)
    return f(X)
>>> do_something([1, 2, 3, 4])
[1, 4, 9, 16]
>>> do_something(2)
4
>>> do_something(iter(range(3, 7)))
[9, 16, 25, 36]

如果您想在第二种情况下返回[4],则需要将其修改为:

def do_something(X):
    return map(lambda x: x**2, X if isinstance(X, Iterable) else [X])

答案 2 :(得分:1)

我建议隐藏你不想在辅助函数中看到的东西:

from collections import Iterable

def make_sure_iterable(X):
    return X if isinstance(X, Iterable) and not isinstance(X, basestring) else [X]

然后当你使用参数包装时调用辅助函数:

def do_something(X):
    return map(lambda x: x, make_sure_iterable(X))