Is there a way to set "array of strings" as a type for a parameter in a function?

Question:

I want to check right at the passing of the arguments to a function if the argument is an array of strings.

Like setting a type to the parameter of the function to “array of string”.
But I don’t want to loop through the array looking for none-string elements.

Is there a type like this?

Asked By: user11435431

||

Answers:

>>> isinstance(["abc", "def", "ghi", "jkl"], list)
True
>>> isinstance(50, list)
False

You could use this inside your function in order to check if your argument is a list.

Answered By: HLupo

The way to make it bullet proof is to check them in the function (sadly iterating over the elements), but using all with a comprehension makes the evaluation lazy and will stop in the first element that is not a string instance:

def foo(my_str_list):
    is_list = isinstance(my_str_list, list) 
    are_strings = all(isinstance(x, str) for x in my_str_list)
    if not is_list or not are_strings:
        raise TypeError("Funtion argument should be a list of strings.")
    ...
Answered By: Netwave

Will a lambda function work?

def check_arr_str(li):

    #Filter out elements which are of type string
    res = list(filter(lambda x: isinstance(x,str), li))

    #If length of original and filtered list match, all elements are strings, otherwise not
    return (len(res) == len(li) and isinstance(li, list))

The outputs will look like

print(check_arr_str(['a','b']))
#True
print(check_arr_str(['a','b', 1]))
#False
print(check_arr_str(['a','b', {}, []]))
#False
print(check_arr_str('a'))
#False

If an exception is needed, we can change the function as follows.

def check_arr_str(li):

    res = list(filter(lambda x: isinstance(x,str), li))
    if (len(res) == len(li) and isinstance(li, list)):
        raise TypeError('I am expecting list of strings')

Another way we can do this is using any to check if we have any item in the list which is not a string, or the parameter is not a list (Thanks @Netwave for the suggestion)

def check_arr_str(li):

    #Check if any instance of the list is not a string
    flag = any(not isinstance(i,str) for i in li)

    #If any instance of an item  in the list not being a list, or the input itself not being a list is found, throw exception
    if (flag or not isinstance(li, list)):
        raise TypeError('I am expecting list of strings')
Answered By: Devesh Kumar Singh

Try this:

l = ["abc", "def", "ghi", "jkl"]  
isinstance(l, list) and all(isinstance(i,str) for i in l)

the output:

In [1]: a = ["abc", "def", "ghi", "jkl"]                                        

In [2]: isinstance(a, list) and all(isinstance(i,str) for i in a)               
Out[2]: True

In [3]: a = ["abc", "def", "ghi", "jkl",2]                                      

In [4]: isinstance(a, list) and all(isinstance(i,str) for i in a)               
Out[4]: False
Answered By: Mehrdad Pedramfar

You can use typing for recent python version (tested on 3.9), as suggested by @Netwave in the comments:

def my_function(a: list[str]):
  # You code

Which will lint as expected:

pycharm linting example

Answered By: KawaLo
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.