J'ai un tableau de bools et maintenant je veux échanger ces entrées contre des nombres.
False => 0
True => 1
J'ai écrit deux morceaux de code différents et j'aimerais savoir lequel est le meilleur et pourquoi. Il ne s'agit pas tant de résoudre réellement le problème que d'apprendre.
arr = [[True,False],[False,True],[True,True]]
for i,row in enumerate(arr):
for j,entry in enumerate(row):
if entry:
arr[i][j] = 1
else:
arr[i][j] = 0
print(arr)
Et la deuxième approche:
arr = [[True,False],[False,True],[True,True]]
for i in range(len(arr)):
for j in range(len(arr[i])):
if arr[i][j]:
arr[i][j] = 1
else:
arr[i][j] = 0
print(arr)
J'ai lu qu'il existe des moyens de le faire avec l'importation de itertools
ou similaire. Je ne suis vraiment pas fan d'importer des choses si cela peut être fait avec des "outils embarqués", mais devrais-je plutôt les utiliser pour ce problème?
Définissons votre tableau:
>>> arr = [[True,False],[False,True],[True,True]]
Maintenant, convertissons les booléens en entier:
>>> [[int(i) for i in row] for row in arr]
[[1, 0], [0, 1], [1, 1]]
Alternativement, si nous voulons être plus flexibles sur ce qui est remplacé, nous pouvons utiliser une déclaration ternaire:
>>> [[1 if i else 0 for i in row] for row in arr]
[[1, 0], [0, 1], [1, 1]]
Si vous souhaitez conserver une boucle for (par exemple parce que vous voulez muter le tableau existant au lieu d'en créer un nouveau), vous devez simplifier le code.
Je simplifierais d'abord la boucle externe en supprimant l'indexation (ce n'est pas nécessaire car il est encore plus facile de modifier une ligne qu'un tableau imbriqué):
for row in arr:
for j, entry in enumerate(row):
if entry:
row[j] = 1
else:
row[j] = 0
ces types d'instructions if simples peuvent souvent être simplifiés en utilisant une expression if:
row[j] = 1 if entry else 0
mais dans ce cas, nous pouvons faire encore mieux. bool
est une sous-classe de int
(c'est-à-dire que tous les bool
sont des int
), et True
et False
sont définis pour être exactement 1
et 0
respectivement - si vous faites défiler jusqu'à la section des spécifications du PEP 285 ( https://www.python.org/dev/peps/ pep-0285 / ) vous verrez que cette équivalence n'est pas accidentelle, mais beaucoup par conception.
Nous pouvons donc utiliser le constructeur int
pour récupérer les valeurs entières sous-jacentes [*], puisque int(True) == 1
et int(False) == 0
, l'expression if peut être simplifiée pour:
row[j] = int(entry)
[*] techniquement, il s'agit d'une conversion ascendante explicite vers une classe de base, et non un constructeur de conversion.
Le code simplifié:
for row in arr:
for j, entry in enumerate(row):
row[j] = int(entry)