如何判断一个变量是可迭代的但不是字符串

新手上路,请多包涵

我有一个接受参数的函数,该参数可以是单项或双项:

 def iterable(arg)
    if #arg is an iterable:
        print "yes"
    else:
        print "no"

以便:

>>> 可迭代((“f”,“f”))
是的

>>> 可迭代的([“f”,“f”])
是的

>>> 可迭代的(“ff”)
不

问题是字符串在技术上是可迭代的,所以我在尝试 arg[1] 时不能只捕获 ValueError 。我不想使用 isinstance(),因为这不是好的做法(或者有人告诉我)。

原文由 priestc 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 445
2 个回答

使用 isinstance (我不明白为什么这是不好的做法)

 import types
if not isinstance(arg, types.StringTypes):

注意 StringTypes 的使用。它确保我们不会忘记一些晦涩的字符串类型。

从好的方面来说,这也适用于派生的字符串类。

 class MyString(str):
    pass

isinstance(MyString("  "), types.StringTypes) # true

另外,您可能想看看这个 previous question

干杯。


注意: Python 3 中的行为已更改为 StringTypesbasestring 不再定义。根据您的需要,您可以将 isinstance 中的它们替换为 str ,或者 (str, bytes, unicode) 的子集元组,例如对于 Cython 用户正如 @Theron Luhn 提到的,您还可以使用 six

原文由 scvalex 发布,翻译遵循 CC BY-SA 3.0 许可协议

截至 2017 年,这是一个适用于所有 Python 版本的便携式解决方案:

 #!/usr/bin/env python
import collections
import six

def iterable(arg):
    return (
        isinstance(arg, collections.Iterable)
        and not isinstance(arg, six.string_types)
    )

# non-string iterables
assert iterable(("f", "f"))    # tuple
assert iterable(["f", "f"])    # list
assert iterable(iter("ff"))    # iterator
assert iterable(range(44))     # generator
assert iterable(b"ff")         # bytes (Python 2 calls this a string)

# strings or non-iterables
assert not iterable(u"ff")     # string
assert not iterable(44)        # integer
assert not iterable(iterable)  # function

原文由 sorin 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题