10

我想要一个将对象包装在一个可迭代对象中的函数,以允许该函数的客户端以相同的方式处理集合和单个对象,我做了以下操作:

 def to_iter(obj):
     try:
         iter(obj)
         return obj
     except TypeError:
         return [obj]

有没有一种pythonic方法可以做到这一点?,如果obj是一个字符串,我想将字符串视为单个对象?,我应该isinstance改用iter吗?

4

3 回答 3

10

您的方法很好:它会将字符串对象转换为可迭代对象

try:
    iter(obj)
except TypeError, te:
    obj = list(obj)

您可以检查的另一件事是:

if not hasattr(obj, "__iter__"): #returns True if type of iterable - same problem with strings
    obj = list(obj)
return obj

检查字符串类型:

import types
if not isinstance(obj, types.StringTypes) and hasattr(obj, "__iter__"):
    obj = list(obj)
return obj
于 2013-05-29T01:47:27.737 回答
3

这是一个带有一些文档测试的通用解决方案来演示:

def is_sequence(arg):
    """
SYNOPSIS
    Test if input is iterable but not a string.

DESCRIPTION
    Type checker. True for any object that behaves like a list, tuple or dict
    in terms of ability to iterate over its elements; but excludes strings.

    See http://stackoverflow.com/questions/1835018

PARAMETERS
    arg         Object to test.

RETURNS
    True or False

EXAMPLES
    ## string
    >>> is_sequence('string')
    False

    ## list
    >>> is_sequence([1, 2, 3,])
    True

    ## set
    >>> is_sequence(set([1, 2, 3,]))
    True

    ## tuple
    >>> is_sequence((1, 2, 3,))
    True

    ## dict
    >>> is_sequence(dict(a=1, b=2))
    True

    ## int
    >>> is_sequence(123)
    False

LIMITATIONS
    TBD
    """
    return (not hasattr(arg, "strip") and
            hasattr(arg, "__iteritems__") or
            hasattr(arg, "__iter__"))


def listify(arg):
    """
SYNOPSIS
    Wraps scalar objects in a list; passes through lists without alteration.

DESCRIPTION
    Normalizes input to always be a list or tuple.  If already iterable and
    not a string, pass through.  If a scalar, make into a one-element list.

    If a scalar is wrapped, the same scalar (not a copy) is preserved.

PARAMETERS
    arg         Object to listify.

RETURNS
    list

EXAMPLES
    >>> listify(1)
    [1]

    >>> listify('string')
    ['string']

    >>> listify(1, 2)
    Traceback (most recent call last):
        ...
    TypeError: listify() takes exactly 1 argument (2 given)

    >>> listify([3, 4,])
    [3, 4]

    ## scalar is preserved, not copied
    >>> x = 555
    >>> y = listify(x)
    >>> y[0] is x
    True

    ## dict is not considered a sequence for this function
    >>> d = dict(a=1,b=2)
    >>> listify(d)
    [{'a': 1, 'b': 2}]

    >>> listify(None)
    [None]

LIMITATIONS
    TBD
    """
    if is_sequence(arg) and not isinstance(arg, dict):
        return arg
    return [arg,]
于 2016-03-15T18:26:33.633 回答
0

我的便携式 pythonic 锤子:

def isstr(o):
  try:
    basestring
  except NameError:
    basestring = (str, bytes)
  return isinstance(o, basestring)

def toiter(o):
  if not isstr(o):
    try:
      return iter(o)
    except TypeError:
      pass
  return iter([o])

def tolist(o):
  if not isstr(o):
    try:
      return list(o)
    except TypeError:
      pass
  return [o]
于 2018-09-11T12:40:16.420 回答