Je pensais comprendre la portée globale et locale de la variable, mais je me débat sur un cas.
Voici la fonction que je veux implémenter:
Id Login 0 1 JohnDoe 1 2 AnnFranklin
Résultat attendu :
Id Login Password 0 1 JohnDoe 987340123 1 2 AnnFranklin 187031122
Sortie que j'ai obtenue:
def login_table(id_name_verified, id_password): """ :param id_name_verified: (DataFrame) DataFrame with columns: Id, Login, Verified. :param id_password: (numpy.array) Two-dimensional NumPy array where each element is an array that contains: Id and Password :returns: (None) The function should modify id_name_verified DataFrame in-place. It should not return anything. Goal : in id_name_verified, 'Verified' column should be removed and password should be added from id_password with corresponding id and the column be named password """ Test: import pandas as pd import numpy as np def login_table(id_name_verified, id_password): id_name_verified.drop(columns="Verified",inplace=True) password = pd.DataFrame(id_password) password.columns = ["Id", "Password"] id_name_verified =id_name_verified.merge(password, on=['Id']) id_name_verified = pd.DataFrame([[1, "JohnDoe", True], [2, "AnnFranklin", False]], columns=["Id", "Login", "Verified"]) id_password = np.array([[1, 987340123], [2, 187031122]], np.int32) login_table(id_name_verified, id_password) print(id_name_verified)
Quand j'exécute ceci sur pycharm, je vois que le problème est dans le dernier ligne de ma fonction où id_name_verified
est identifié comme étant de la portée externe.
Cette inspection détecte les noms d'ombrage définis dans les portées externes.
Si je ne définit pas de fonction, cela fonctionnera donc je suppose qu'il y a quelque chose qui me manque dans la compréhension des paramètres transmis à une fonction; des suggestions?
3 Réponses :
Voici le code qui résoudra votre problème:
import pandas as pd import numpy as np def login_table( id_password): global id_name_verified id_name_verified.drop(columns="Verified",inplace=True) password = pd.DataFrame(id_password) password.columns = ["Id", "Password"] id_name_verified =id_name_verified.merge(password, on=['Id']) id_name_verified = pd.DataFrame([[1, "JohnDoe", True], [2, "AnnFranklin", False]], columns=["Id", "Login", "Verified"]) id_password = np.array([[1, 987340123], [2, 187031122]], np.int32) login_table( id_password) print(id_name_verified)
Les modifications que j'ai apportées sont, j'ai déclaré le "id_name_verified" comme global dans la fonction "login_table". Une fois cela fait, vous n'avez pas à passer à nouveau "id_name_verified" à la fonction car en utilisant le mot-clé "global" nous avons déjà donné accès de "id_name_verified" à la fonction "login_table". Donc supprimé le "id_name_verified" comme l'un des arguments de la fonction.
En tant que programmeur, vous devriez essayer très, très, très difficilement pas d’utiliser des variables globales!
Voici le code qui réussit les 4 tests sur TestDome:
import pandas as pd import numpy as np def login_table(id_name_verified, id_password): """ :param id_name_verified: (DataFrame) DataFrame with columns: Id, Login, Verified. :param id_password: (numpy.array) Two-dimensional NumPy array where each element is an array that contains: Id and Password :returns: (None) The function should modify id_name_verified DataFrame in-place. It should not return anything. """ id_name_verified.drop(columns = 'Verified', inplace = True) password_df = pd.DataFrame(id_password) pass_col = password_df[1] id_name_verified['Password'] = pass_col id_name_verified = pd.DataFrame([[1, "JohnDoe", True], [2, "AnnFranklin", False]], columns=["Id", "Login", "Verified"]) id_password = np.array([[1, 987340123], [2, 187031122]], np.int32) login_table(id_name_verified, id_password) print(id_name_verified)
Vous supprimez la colonne 'Vérifié', puis créez un nouveau bloc de données juste en dehors de id_password, prenez la colonne qui contient les mots de passe et ajoutez-le à la trame de données id_name_verified.
import pandas as pd import numpy as np def login_table(id_name_verified, id_password): # in place makes sure that changes are made in a current dataframe id_name_verified.drop('Verified', 1, inplace= True) # id_password[:,1] -> : selects all rows and 1 selects only second column id_name_verified['Password'] = id_password[:,1] pass id_name_verified = pd.DataFrame([[1, "JohnDoe", True], [2, "AnnFranklin", False]], columns=["Id", "Login", "Verified"]) id_password = np.array([[1, 987340123], [2, 187031122]], np.int32) login_table(id_name_verified, id_password) print(id_name_verified)
Ce n'est pas un problème de variables globales vs locales (à part l'avertissement pycharm sur l'observation).
login_table ()
doitrenvoyer id_name_verified
et le site d'appel doit être:id_name_verified = login_table (id_name_verified, id_password)
Je comprends ce que vous voulez dire mais si je veux satisfaire les spécifications de la fonction, je ne veux pas que la fonction renvoie quelque chose, alors modifiez-la en place comme je l'ai dit, et ne changez pas le nombre de paramètre