Comment convertir des chaînes en entiers en Python?


438

J'ai un tuple de tuples d'une requête MySQL comme ceci:

T1 = (('13', '17', '18', '21', '32'),
      ('07', '11', '13', '14', '28'),
      ('01', '05', '06', '08', '15', '16'))

Je voudrais convertir tous les éléments de chaîne en entiers et les remettre dans une liste de listes:

T2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]

J'ai essayé d'y parvenir evalmais je n'ai pas encore obtenu de résultat décent.


2
Peut-être envisager un module d'adaptateur de base de données différent? Je sais que les modules adaptateurs PostgreSQL renverront des résultats comme votre ensemble T2.
kquinn

3
Copie possible de la chaîne d'analyse à Float ou Int
Nathan

veuillez noter: lorsque vous utilisez map, vous obtiendrez une liste des objets map en python 3 et 3.5. Cela le fait pour Python 3.5 comme mentionné ci-dessus. new_list = list (list (int (a) for a in b) for b in T1 if a.isdigit ())
Guest

Question similaire pour une liste non imbriquée: convertir toutes les chaînes d'une liste en int
Aran-Fey

Réponses:


630

int()est la fonction intégrée standard de Python pour convertir une chaîne en une valeur entière. Vous l'appelez avec une chaîne contenant un nombre comme argument, et il retourne le nombre converti en entier:

print (int("1") + 1)

Les impressions ci-dessus 2.

Si vous connaissez la structure de votre liste, T1 (qu'elle contient simplement des listes, un seul niveau), vous pouvez le faire en Python 2:

T2 = [map(int, x) for x in T1]

En Python 3:

T2 = [list(map(int, x)) for x in T1]

4
pourquoi pas T2 = map(lambda lol: map(int, lol), T1)? Soit carte ou liste compréhensions, les deux est stupide;)
mouton volant

4
@flyingsheep Double map me semble idiot, cela semble très bien.
jamylak

Que diriez-vous de supprimer l'exemple Python 2 (en raison de la fin de vie de Python2)?
Alisso

28

Vous pouvez le faire avec une liste de compréhension:

T2 = [[int(column) for column in row] for row in T1]

La liste intérieure comprehension ( [int(column) for column in row]) construit un listde ints à partir d'une séquence d' intobjets -able, comme des chaînes décimales, dans row. La compréhension de la liste externe ( [... for row in T1])) construit une liste des résultats de la compréhension de la liste interne appliquée à chaque élément dans T1.

L'extrait de code échouera si l'une des lignes contient des objets qui ne peuvent pas être convertis par int. Vous aurez besoin d'une fonction plus intelligente si vous souhaitez traiter des lignes contenant des chaînes non décimales.

Si vous connaissez la structure des lignes, vous pouvez remplacer la compréhension de la liste interne par un appel à une fonction de la ligne. Par exemple.

T2 = [parse_a_row_of_T1(row) for row in T1]

16

Je préfère utiliser uniquement des listes de compréhension:

[[int(y) for y in x] for x in T1]

12

Au lieu de mettre int( ), mettez float( )qui vous permettra d'utiliser des décimales avec des entiers.


2
Pouvez-vous expliquer plus de détails sur votre réponse?
Rico

10

Je suis d'accord avec les réponses de tout le monde jusqu'à présent, mais le problème est que si vous n'avez pas tous les nombres entiers, ils planteront.

Si vous vouliez exclure des non-entiers,

T1 = (('13', '17', '18', '21', '32'),
      ('07', '11', '13', '14', '28'),
      ('01', '05', '06', '08', '15', '16'))
new_list = list(list(int(a) for a in b) for b in T1 if a.isdigit())

Cela ne donne que des chiffres réels. La raison pour laquelle je n'utilise pas de compréhension de liste directe est que la compréhension de liste laisse échapper leurs variables internes.


2
isdigitest délicat, essayez-le -1. int(<str>)est le moyen de vérifier par try/ except.
totoro

9
T3=[]

for i in range(0,len(T1)):
    T3.append([])
    for j in range(0,len(T1[i])):
        b=int(T1[i][j])
        T3[i].append(b)

print T3

7
Bienvenue dans Stack Overflow! Plutôt que de publier uniquement un bloc de code, veuillez expliquer pourquoi ce code résout le problème posé. Sans explication, ce n'est pas une réponse.
Artemix

7

Essaye ça.

x = "1"

x est une chaîne car elle est entourée de guillemets, mais elle contient un nombre.

x = int(x)

Puisque x contient le numéro 1, je peux le transformer en un entier.

Pour voir si une chaîne est un nombre, vous pouvez le faire.

def is_number(var):
    try:
        if var == int(var):
            return True
    except Exception:
        return False

x = "1"

y = "test"

x_test = is_number(x)

print(x_test)

Il doit imprimer sur IDLE True car x est un nombre.

y_test = is_number(y)

print(y_test)

Il doit imprimer sur IDLE False car y n'est pas un nombre.


2
Votre fonction is_number est incorrecte. '1' n'est pas égal à 1. Ce n'est pas Perl. :-P
Veky

3
Ne réinventez pas la roue, utilisez x.isnumeric().
bfontaine

4

Utilisation de listes de compréhension:

t2 = [map(int, list(l)) for l in t1]

1
en python 3, cela retourne une liste d'objets cartographiques :(
CpILL

3

Dans Python 3.5.1, des choses comme celles-ci fonctionnent:

c = input('Enter number:')
print (int(float(c)))
print (round(float(c)))

et

Enter number:  4.7
4
5

George.


3

Voir cette fonction

def parse_int(s):
    try:
        res = int(eval(str(s)))
        if type(res) == int:
            return res
    except:
        return

alors

val = parse_int('10')  # Return 10
val = parse_int('0')  # Return 0
val = parse_int('10.5')  # Return 10
val = parse_int('0.0')  # Return 0
val = parse_int('Ten')  # Return None

Vous pouvez également vérifier

if val == None:  # True if input value can not be converted
    pass  # Note: Don't use 'if not val:'

evalest mauvais: vous devez le remplacer par ast.literal_eval.
Eli Korvigo du

3

Encore une autre solution fonctionnelle pour Python 2:

from functools import partial

map(partial(map, int), T1)

Python 3 sera un peu désordonné cependant:

list(map(list, map(partial(map, int), T1)))

nous pouvons résoudre ce problème avec un wrapper

def oldmap(f, iterable):
    return list(map(f, iterable))

oldmap(partial(oldmap, int), T1)

1

Si ce n'est qu'un tuple de tuples, quelque chose comme rows=[map(int, row) for row in rows]ça fera l'affaire. (Il y a une compréhension de la liste et un appel à la carte (f, lst), qui est égal à [f (a) pour a in lst], là-dedans.)

Eval n'est pas ce que vous voulez faire, au cas où il y aurait quelque chose comme __import__("os").unlink("importantsystemfile")dans votre base de données pour une raison quelconque. Validez toujours votre entrée (si rien d'autre, l'exception int () se lèvera si vous avez une mauvaise entrée).


-1

Vous pouvez faire quelque chose comme ça:

T1 = (('13', '17', '18', '21', '32'),  
     ('07', '11', '13', '14', '28'),  
     ('01', '05', '06', '08', '15', '16'))  
new_list = list(list(int(a) for a in b if a.isdigit()) for b in T1)  
print(new_list)  

-1

Je souhaite partager une option disponible qui ne semble pas encore être mentionnée ici:

rumpy.random.permutation(x)

Générera une permutation aléatoire du tableau x. Pas exactement ce que vous avez demandé, mais c'est une solution potentielle à des questions similaires.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.