Wie konvertiere ich Strings in Python in Ganzzahlen?

438

Ich habe ein Tupel von Tupeln aus einer MySQL-Abfrage wie folgt:

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

Ich möchte alle Zeichenfolgenelemente in Ganzzahlen konvertieren und sie wieder in eine Liste von Listen einfügen:

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

Ich habe versucht, es mit zu erreichen, evalaber noch kein anständiges Ergebnis erzielt.

elfuego1
quelle
2
Vielleicht ein anderes Datenbankadaptermodul in Betracht ziehen? Ich weiß, dass die PostgreSQL-Adaptermodule Ergebnisse wie Ihr T2-Set zurückgeben.
Kquinn
3
Mögliches Duplikat von Parse String to Float oder Int
Nathan
Bitte beachten Sie: Wenn Sie map verwenden, erhalten Sie eine Liste der Kartenobjekte in Python 3 und 3.5. Dies geschieht für Python 3.5 wie oben erwähnt. new_list = Liste (Liste (int (a) für a in b) für b in T1, wenn a.isdigit ())
Gast
Ähnliche Frage für eine nicht verschachtelte Liste: Konvertieren Sie alle Zeichenfolgen in einer Liste in int
Aran-Fey

Antworten:

630

int()ist die in Python integrierte Standardfunktion zum Konvertieren eines Strings in einen ganzzahligen Wert. Sie rufen es mit einer Zeichenfolge auf, die eine Zahl als Argument enthält, und es gibt die in eine Ganzzahl konvertierte Zahl zurück:

print (int("1") + 1)

Die obigen Drucke 2.

Wenn Sie die Struktur Ihrer Liste T1 kennen (die lediglich Listen enthält, nur eine Ebene), können Sie dies in Python 2 tun:

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

In Python 3:

T2 = [list(map(int, x)) for x in T1]
entspannen
quelle
4
warum nicht T2 = map(lambda lol: map(int, lol), T1)? Entweder Karten- oder Listenverständnisse, beides ist albern;)
fliegende Schafe
4
@flyingsheep Doppelkarte scheint mir albern, das scheint in Ordnung zu sein.
Jamylak
Wie wäre es mit dem Entfernen des Python 2-Beispiels (wegen des Lebensendes für Python2)?
Alisso
28

Sie können dies mit einem Listenverständnis tun:

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

Das innere Listenverständnis ( [int(column) for column in row]) baut ein listvon ints aus einer Folge von int-able Objekten wie Dezimalzeichenfolgen in auf row. Das äußere Listenverständnis ( [... for row in T1])) erstellt eine Liste der Ergebnisse des inneren Listenverständnisses, das auf jedes Element in angewendet wird T1.

Das Code-Snippet schlägt fehl, wenn eine der Zeilen Objekte enthält, die nicht konvertiert werden können int . Sie benötigen eine intelligentere Funktion, wenn Sie Zeilen mit nicht dezimalen Zeichenfolgen verarbeiten möchten.

Wenn Sie die Struktur der Zeilen kennen, können Sie das Verständnis der inneren Liste durch einen Aufruf einer Funktion der Zeile ersetzen. Z.B.

T2 = [parse_a_row_of_T1(row) for row in T1]
Will Harris
quelle
16

Ich würde lieber nur Verständnislisten verwenden:

[[int(y) for y in x] for x in T1]
odwl
quelle
12

Anstatt zu setzen int( ), setzen Sie, float( )wodurch Sie Dezimalstellen zusammen mit ganzen Zahlen verwenden können.

weir99
quelle
2
Können Sie mehr Details zu Ihrer Antwort erklären?
Rico
10

Ich würde allen bisherigen Antworten zustimmen, aber das Problem ist, dass wenn Sie nicht alle ganzen Zahlen haben, diese abstürzen.

Wenn Sie dann Nicht-Ganzzahlen ausschließen möchten

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

Dies ergibt nur tatsächliche Ziffern. Der Grund, warum ich kein direktes Listenverständnis verwende, ist, dass das Listenverständnis ihre internen Variablen verliert.

Christian Witts
quelle
2
isdigitist schwierig, probier es an -1. int(<str>)ist der Weg, um durch try/ zu überprüfen 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
quelle
7
Willkommen bei Stack Overflow! Erklären Sie bitte, warum dieser Code das aufgeworfene Problem löst, anstatt nur einen Codeblock zu veröffentlichen. Ohne eine Erklärung ist dies keine Antwort.
Artemix
7

Versuche dies.

x = "1"

x ist eine Zeichenfolge, weil sie in Anführungszeichen gesetzt ist, aber eine Zahl enthält.

x = int(x)

Da x die Nummer 1 enthält, kann ich sie in eine Ganzzahl umwandeln.

Um festzustellen, ob eine Zeichenfolge eine Zahl ist, können Sie dies tun.

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)

Es sollte in IDLE True gedruckt werden, da x eine Zahl ist.

y_test = is_number(y)

print(y_test)

Es sollte in IDLE False gedruckt werden, da y keine Zahl ist.

TheRedstoneLemon
quelle
2
Ihre is_number-Funktion ist falsch. '1' ist nicht gleich 1. Dies ist nicht Perl. :-P
Veky
3
Das Rad nicht neu erfinden, benutzen x.isnumeric().
Bfontaine
4

Listenverständnis verwenden:

t2 = [map(int, list(l)) for l in t1]
Jon
quelle
1
in Python 3 gibt dies eine Liste von Kartenobjekten zurück :(
CpILL
3

In Python 3.5.1 funktionieren solche Dinge:

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

und

Enter number:  4.7
4
5

George.

George Moraitis
quelle
3

Siehe diese Funktion

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

Dann

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

Sie können auch überprüfen

if val == None:  # True if input value can not be converted
    pass  # Note: Don't use 'if not val:'
Shameem
quelle
evalist böse: du solltest es durch ersetzen ast.literal_eval.
Eli Korvigo
3

Noch eine funktionale Lösung für Python 2:

from functools import partial

map(partial(map, int), T1)

Python 3 wird allerdings etwas chaotisch sein:

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

Wir können dies mit einem Wrapper beheben

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

oldmap(partial(oldmap, int), T1)
Eli Korvigo
quelle
1

Wenn es nur ein Tupel von Tupeln ist, reicht so etwas aus rows=[map(int, row) for row in rows]. (Es gibt dort ein Listenverständnis und einen Aufruf zur Zuordnung (f, lst), der gleich [f (a) für a in lst] ist.)

Eval ist nicht das, was Sie tun möchten, falls sich __import__("os").unlink("importantsystemfile")aus irgendeinem Grund so etwas in Ihrer Datenbank befindet. Überprüfen Sie immer Ihre Eingabe (wenn nichts anderes vorhanden ist, wird die Ausnahme int () ausgelöst, wenn Sie eine schlechte Eingabe haben).

AKX
quelle
-1

Sie können so etwas tun:

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
quelle
-1

Ich möchte eine verfügbare Option teilen, die hier noch nicht erwähnt zu sein scheint:

rumpy.random.permutation(x)

Erzeugt eine zufällige Permutation des Arrays x. Nicht genau das , wonach Sie gefragt haben, aber es ist eine mögliche Lösung für ähnliche Fragen.

samvoit4
quelle