1
votes

Existe-t-il un moyen de définir "tableau de chaînes" comme type pour un paramètre dans une fonction?

Je veux vérifier dès le passage des arguments à une fonction si l'argument est un tableau de chaînes.

Comme définir un type pour le paramètre de la fonction sur "tableau de chaînes". Mais je ne veux pas parcourir le tableau à la recherche d'éléments sans chaîne.

Existe-t-il un type comme celui-ci?


2 commentaires

Vous pouvez utiliser la saisie et mypy-lang.org , mais c'est juste pour les vérifier pendant le développement, le code serait toujours "courir" de toute façon. Le meilleur moyen de les appliquer est de le vérifier correctement dans la fonction.


Vous ne pouvez pas éviter de parcourir toute la liste. Vous devez regarder chaque élément et vérifier s'il s'agit d'une chaîne.


4 Réponses :


1
votes
>>> 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.

1 commentaires

Oh, merci pour la réponse, mais j'essaie en fait de définir le type entier "liste de chaînes" (j'ai dit "tableau" plus tôt mais c'est "liste" en fait). Définir uniquement le type de chaîne, peut le faire. Définir uniquement le type de liste, peut le faire. Définissez le type «liste de chaînes», impossible de le faire.



0
votes

La façon de le rendre à l'épreuve des balles est de les vérifier dans la fonction (malheureusement en itérant sur les éléments), mais utiliser all avec une compréhension rend l'évaluation paresseuse et s'arrêtera dans le premier élément qui n'est pas une instance de chaîne:

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.")
    ...


2 commentaires

Grand merci. Dans ce cas, en fait, je lèverais un TypeError parce que j'essaie de dire aux appelants de la fonction que le type d'argument doit être une liste de chaînes.


En effet, le TypeError a beaucoup plus de sens ici.



0
votes

Une fonction lambda fonctionnera-t-elle?

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

Les sorties ressembleront à

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

Si une exception est nécessaire, nous pouvons modifier le fonctionne comme suit.

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

Une autre façon de faire est d'utiliser any pour vérifier si nous avons un élément dans la liste qui n'est pas une chaîne , ou le paramètre n'est pas une liste (merci @Netwave pour la suggestion)

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


8 commentaires

Merci! Heureux de vous aider! Si la réponse vous convient, pensez à la marquer comme acceptée et à voter pour @TeodoroMendes :)


hmmm super, j'ai aimé ça. Peut-être ai-je trouvé un moyen de réduire davantage la taille de votre code: if list (filter (lambda x: not isinstance (x, str), li)): rise TypeError ('J'attends une liste de chaînes') Merci!


Cela pourrait ne pas fonctionner si vous ne passez qu'une seule chaîne, pouvez-vous l'essayer?


Je vais laisser cela comme une note pour les lecteurs suivants: Cette version est ok, mais manque de paresseux et fera évaluer la liste complète à chaque fois. Si vous étiez préoccupé par l'itération de la liste entière, cela le fera à chaque fois, et vous construisez une liste intermédiaire en mémoire lorsque cela est totalement inutile.


J'ai essayé et ça a marché! Avez-vous remarqué tous mes changements? Je reçois maintenant une liste des objets qui ne sont PAS une instance de chaîne à la fonction de filtre. Et puis, si la liste existe, il y a un mauvais élément. Même en passant une seule chaîne, cela fonctionne.


@Netwave J'ai fini par réaliser que je devais parcourir la liste jusqu'à ce que je trouve une erreur, le pire des cas: il n'y a pas d'erreur (ou est-ce le meilleur des cas? Haha). Mais vous avez raison en ce sens que, dès que je trouve une erreur, je devrais interrompre le filtrage de la liste. Mais je ne sais pas si cela est possible du tout.


Merci pour la suggestion @Netwave, j'ai repensé et ajouté un exemple qui utilise any pour vérifier si nous trouvons un élément qui n'est pas une chaîne! Bien que je ne sois pas sûr si l'un fonctionnera mieux ici, ou tous , je pense que les deux conditions fonctionneront également bien?


vous êtes juste en train de retourner la condition, donc oui, ofc va fonctionner.



0
votes

Essayez ceci:

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

la sortie:

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


1 commentaires

Ceci est correct non plus, et ensuite lève le TypeError. Merci.