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.

elfuego1
la source
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]
se détendre
la source
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]
Will Harris
la source
16

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

[[int(y) for y in x] for x in T1]
chouette
la source
12

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

weir99
la source
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.

Christian Witts
la source
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
P.Hunter
la source
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.

TheRedstoneLemon
la source
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]
Jon
la source
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.

George Moraitis
la source
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:'
Shameem
la source
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)
Eli Korvigo
la source
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).

AKX
la source
-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)  
Amit Rawat
la source
-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.

samvoit4
la source