Как проверить, является ли объект списком строк?

Как проверить, является ли объект списком строк? Я мог только проверить, является ли объект строкой как таковой:

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)

желаемый результат:

It's a list of strings
It's not a list of strings or a single string
It's a single string

3 ответов


что-то вроде этого, я полагаю? Вы можете сделать некоторые проверки, чтобы увидеть, если это одна строка.

>>> 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 так как это общий класс, из которого оба str и unicode типы наследования. Проверка только str на unicode типы.

по состоянию на Стивен Rumbalski это предложения, если вам нужно в частности, проверьте список строк, которые вы могли бы сделать.

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

редактировать - а в abarnert это предложение, вы также можете проверить на list вместо not isinstance(lst, basestring), код будет переписан как.

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

отойдя от одного лайнера, мы могли бы использовать.

>>> 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 встроенный и генератор:

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

обратите внимание, что, если ваш список пуст, это все равно вернется True поскольку это технически список из 0 строк. Однако, так как вы хотите рассмотреть [] как False, вам нужно будет сделать это:

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

Итак, ваша функция должна быть примерно такой:

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 (не строку). Это позволяет работать с очень большими списками достаточно эффективно.


ответы, которые я читал до сих пор, вызывают exepctions при задании не-списка, который не является строкой...и не является итерационным. Этот вопрос рассматривается в:

в Python, как я могу определить, если объект является итерируемым?

принимая подход типа утки:

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)

выход:

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