关于类型:python:检查对象是否是字符串列表

Python: Check if an object is a list of strings

如何检查对象是否是字符串列表?我只能检查对象是否为字符串,如下所示:

1
2
3
4
5
6
7
8
9
10
def checktype(obj):
  if isinstance(obj,str):
    print"It's a string"

obj1 = ['foo','bar','bar','black','sheet']
obj2 = [1,2,3,4,5,'bar']
obj3 = 'bar'

for i in [obj1,obj2,obj3]:
  checktype(i)

期望输出:

1
2
3
It's a list of strings
It'
s not a list of strings or a single string
It's a single string


我想是这样吧?你可以做些检查看看它是不是一根绳子。

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> def checktype(obj):
        return bool(obj) and all(isinstance(elem, basestring) for elem in obj)

>>> obj1 = ['foo','bar','bar','black','sheet']
>>> obj2 = [1,2,3,4,5,'bar']
>>> obj3 = 'bar'
>>> for i in [obj1, obj2, obj3] :
        print checktype(i)


True
False
True

为什么要检查basestring而不是str

您应该检查basestring而不是str,因为它是strunicode类型都继承自的公共类。只检查str就可以省去unicode类型。

根据StevenRumbalski的建议,如果您需要专门检查字符串列表,可以这样做。

1
2
3
4
5
6
7
8
9
10
11
>>> def is_list_of_strings(lst):
        return bool(lst) and not isinstance(lst, basestring) and all(isinstance(elem, basestring) for elem in lst)
        # You could break it down into `if-else` constructs to make it clearer to read.

>>> for i in [obj1, obj2, obj3] :
        print is_list_of_strings(i)


True
False
False

编辑-根据Abarner的建议,您还可以检查list,而不是not isinstance(lst, basestring),代码将被重写为。

1
2
3
4
5
6
7
8
9
10
11
>>> def is_list_of_strings(lst):
        return bool(lst) and isinstance(lst, list) and all(isinstance(elem, basestring) for elem in lst)
        # You could break it down into `if-else` constructs to make it clearer to read.

>>> for i in [obj1, obj2, obj3] :
        print is_list_of_strings(i)


True
False
False

离开一条航线,我们可以使用。

1
2
3
4
5
>>> def is_list_of_strings(lst):
        if lst and isinstance(lst, list):
            return all(isinstance(elem, basestring) for elem in lst)
        else:
            return False


要测试列表中的所有项是否都是字符串,请使用all内置和生成器:

1
if all(isinstance(s, str) for s in lis):

注意,尽管如此,如果您的列表是空的,这仍然会返回True,因为从技术上讲,这是一个0字符串的列表。但是,由于您希望将[]视为False,您需要这样做:

1
if lis and all(isinstance(s, str) for s in lis):

所以,你的函数应该是这样的:

1
2
3
4
5
6
def checktype(obj):
    # This if statement makes sure input is a list that is not empty
    if obj and isinstance(obj, list):
        return all(isinstance(s, str) for s in obj)
    else:
        return False

如果该函数的输入是一个不为空且完全由字符串组成的列表,则该函数只返回True。任何其他东西(如[]['a', 1]('a', 'b')等)都会使它返回False

此外,以这种方式使用all还有一个额外的好处,即它停止检查它发现返回False的第一个项目(不是字符串)。这使您能够非常有效地处理非常大的列表。


到目前为止,我所读到的答案在给出一个非字符串的列表时会引发一些异常情况……而且也不可重复。这个问题的解决方法是:

在Python中,如何确定一个对象是否是不可访问的?

采用鸭式打字方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def categorize(x):
    result ="not a string or list of strings"
    if isinstance(x, basestring):
        return"It's a single string"
    try:
        if all(isinstance(y, basestring) for y in x):
            return"It's a list of strings"
    except TypeError:
        pass
    return"It's not a list of strings or a single string"

data = [ 5,"xyzzy", list("xyzzy"), ['1', '23', 456]]
for x in data:
    print x, categorize(x)

输出:

1
2
3
4
5 It's not a list of strings or a single string
xyzzy It'
s a single string
['x', 'y', 'z', 'z', 'y'] It's a list of strings
['
1', '23', 456] It's not a list of strings or a single string

这个答案是针对python 3的。例如,如果变量名为pins

1
2
if not (pins and isinstance(pins, list) and all(isinstance(pin, str) for pin in pins)):
    raise TypeError('pins must be a list of one or more strings.')

它检查三件事:

  • 是否为非空?
  • 这是一张单子吗?
  • 它包含字符串吗?
  • 如果还需要检查字符串的唯一性,请包括以下第四项检查:

    1
    and (len(tokens) == len(set(tokens)))