Seite 1 von 2

Array (vorher in String, dann) in Integer umwandeln

Verfasst: Montag 25. Januar 2010, 15:31
von human
hi @ all,

es geht darum, dass ich mir eine Liste mit 3 Elementen [1, 2, 3, 4] in einen Integer mit dem Wert 1234 umwandeln will. Ich dachte mir, dass ich die 4 jeweils per

Code: Alles auswählen

string = "".join(Liste)
in einen String umwandle, den ich dann per

Code: Alles auswählen

integer = int(string)


in einen Integer umwandle...

das funktioniert aber nicht, und Google spuckt außer dem genannten auch nichts aus. Könnte mir vielleicht jemand einen weiterführenden Link oder einen Tipp geben?

€: ich verwende Python3.1

Verfasst: Montag 25. Januar 2010, 15:59
von Dav1d
Es liegt wahrscheinlich daran dass du Integerwerte in der Liste hast

Code: Alles auswählen

int(''.join([str(i) for i in [1,2,3,4]]))
Alerrdings gibt es bestimmt noch was schöneres. Ansonsten wäre ein Traceback nicht schlecht

Verfasst: Montag 25. Januar 2010, 16:02
von fabi1511
Wenn die Elemente der Liste integers sind, wird der Interpreter schon bei der join Anweisung probleme machen
Wenn du diesen Ansatz weiter verfolgen willst, müsste das etwa so aussehen

Code: Alles auswählen

string="".join([str(i) for i in Liste])
integer=int(string)
Ein weiterer interesannter Ansatz wäre die sum Funktion, etwa so:

Code: Alles auswählen

integer=sum([Liste[::-1][i]*10**i for i in xrange(len(Liste))])
Ich bin mir sicher dieser Ansatz lässt sich noch optimieren, aber ich denke das Prinzip kommt rüber

Ich verwende zwar noch Python2.6 aber soweit ich weiß dürfte es hierbei keine Probleme geben

edit: zu langsam...

Verfasst: Montag 25. Januar 2010, 16:28
von derdon
Sowohl sum als auch str.join nehmen auch GEs entgegen:

Code: Alles auswählen

int(''.join(str(i) for i in [1,2,3,4]))

Verfasst: Montag 25. Januar 2010, 16:36
von Defnull
Die meiner Meinung nach saubersten Lösungen wären (je nach Geschmack):

Code: Alles auswählen

>>> sum(v*10**i for i, v in enumerate(reversed([1,2,3,4])))
1234
>>> reduce(lambda x, y: x*10+y, [1,2,3,4])
1234

Verfasst: Dienstag 26. Januar 2010, 08:19
von /me
Defnull hat geschrieben:

Code: Alles auswählen

>>> sum(v*10**i for i, v in enumerate(reversed([1,2,3,4])))
1234
Das gefällt mir ausgezeichnet. Ich hatte auch so eine Lösung, aber ohne reverse(), so dass vorne ein unschönes len(Liste)-i rumstand.

Verfasst: Dienstag 26. Januar 2010, 09:22
von Defnull
Auch wenn ich sonst eher gegen die Verwendung von reduce() bin, da es schwer nach zu vollziehen ist, finde ich es in diesem Fall sogar mal richtig sinnvoll.

Verfasst: Dienstag 26. Januar 2010, 10:08
von human
danke erstmal für die vielen Antworten ;-)

so:
Auch wenn ich sonst eher gegen die Verwendung von reduce() bin, da es schwer nach zu vollziehen ist, finde ich es in diesem Fall sogar mal richtig sinnvoll.
Da hast du verdammt recht^^ - nach 30min und zu zweit war er dann verständlich. Nichtsdestotrotz ist es ein wirklich schicker Code, und dadurch, dass ich in meinem Script mehrere, unterschiedlich lange Listen hab ist der wie dafür gemacht...

Meine Frage wäre damit eigentlich beantwortet. Ich denke, der Thread kann geclosed werden!

Gruß human

Verfasst: Dienstag 26. Januar 2010, 15:05
von Klip

Code: Alles auswählen

>>> toInt = lambda x: int(''.join(map(str, x)))
>>> toInt('1234')
1234
>>> toInt(range(5))
1234
oder ohne lambda:

Code: Alles auswählen

int(''.join(map(str, Liste)))
Finde ich verständlicher als die reduce-Variante (allerdings unsauberer) und intuitiver als die List-comprehension, aber das hängt wohl vom Anwender ab :)

Verfasst: Dienstag 26. Januar 2010, 15:13
von HWK
Das entspricht ja im Prinzip Dav1ds Variante, wobei ich eher einen Generator statt einer LC verwenden würde.
MfG
HWK

Verfasst: Dienstag 26. Januar 2010, 15:15
von snafu
Ich finde gerade LCs intuitiver als `map()`, denn bei letzterem muss man als unerfahrener Programmierer auch erstmal wissen, was ein `map()` tut, wobei es im Grunde auf der selben Stufe mit `reduce()` steht. Bei `reduce()` hab ich mir auch einmal kurz die Doku angeguckt, insb. das Beispiel, dann geguckt, was Defnull gemacht hat und welche Intention das wohl hatte und fertig. Vom mathematischen her finde ich diesen Ansatz wesentlich klarer. Wie gesagt: Ob man jetzt lernt, was `map()` und `join()` tun und dass man da 2 Typumwandlungen braucht, oder ob man guckt, was `lambda` und `reduce` machen und kurz überlegt, wozu die Berechnung gut ist, sollte eigentlich der gleiche Aufwand sein. Das Vermeiden von neuen Funktionen hilft ja auf Dauer auch nicht weiter und wer öfter mal mit verschiedenen Basen für `int()` arbeitet, sollte die Variante von Defnull ohnehin nicht so abwegig finden.

Verfasst: Dienstag 26. Januar 2010, 17:16
von Defnull
Wenn man sich wirklich darum sorgt, das man selbst oder ein Anderer beim Lesen des Codes über den Ausdruck stolpert, kann man ein Feature namens "Kommentar" nutzen, um die Codestelle zu erklären. Umwege über Strings zu nehmen, nur weil es dann verständlicher wird, halte ich für kontraproduktiv.

Und eigentlich muss man das ja auch nicht verstehen, solange man weiß, was am Ende bei raus kommt und damit rechnen kann. Wenn es den Leser wirklich interessiert, schlägt er halt nach, was reduce() tut.

Code: Alles auswählen

someint = reduce(lambda x, y: x*10+y, somelistofints) # [1,2,3,4] --> 1234
Und fürs Verständnis: reduce() tut das folgende:

Code: Alles auswählen

l = [1,2,3,4]
x = l[0]
for i in l[1:]:
    x *= 10
    x += i
Ich finde map() und filter() übrigens weitaus überflüssiger, als reduce(). Im Gegensatz zu reduce() kann man diese zwei nämlich problemlos durch LCs ersetzen. Wenn es um die Geschmacksfrage "LG gegen generator" geht, muss man also dazu sagen, um welche Generatoren es sich handelt. reduce() ist ziemlich sinnvoll, wenn man seine Funktion einmal kapiert hat.

Verfasst: Dienstag 26. Januar 2010, 17:31
von DasIch
Defnull hat geschrieben:Ich finde map() und filter() übrigens weitaus überflüssiger, als reduce(). Im Gegensatz zu reduce() kann man diese zwei nämlich problemlos durch LCs ersetzen.
filter() mag sich einfach ersetzen lassen, map() kann allerdings schon etwas mehr als eine einfache LC.

Verfasst: Dienstag 26. Januar 2010, 17:56
von EyDu
DasIch hat geschrieben:map() kann allerdings schon etwas mehr als eine einfache LC.
Und das soll was sein? Und jetzt antworte bitte nicht das eingesparte zip ;-)

Verfasst: Dienstag 26. Januar 2010, 18:19
von DasIch
Eine LC mit dem zip sieht dumm aus. :(

Verfasst: Mittwoch 27. Januar 2010, 08:24
von jens
derdon hat geschrieben:

Code: Alles auswählen

int(''.join(str(i) for i in [1,2,3,4]))
Also die Lösung finde ich noch am besten. Kann man am schnellsten verstehen.

Verfasst: Donnerstag 28. Januar 2010, 14:06
von Leonidas
jens hat geschrieben:
derdon hat geschrieben:

Code: Alles auswählen

int(''.join(str(i) for i in [1,2,3,4]))
Also die Lösung finde ich noch am besten. Kann man am schnellsten verstehen.
Also ich finde die ziemlich hässlich. Eine Zahl in einen String zu konvertieren, diesen dann zusammenzukonkatenieren und wieder in einen Int zu wandeln kommt mir "unsauber" vor.

Verfasst: Donnerstag 28. Januar 2010, 16:39
von derdon
Mir auch. Ich finde das zweite Beispiel von defnull am schönsten. Mein Code-Beispiel war nur dazu da, um zu zeigen, dass str.join statt LCs auch GEs entgegen nimmt.

Verfasst: Donnerstag 28. Januar 2010, 16:45
von EyDu
derdon hat geschrieben:Mir auch. Ich finde das zweite Beispiel von defnull am schönsten. Mein Code-Beispiel war nur dazu da, um zu zeigen, dass str.join statt LCs auch GEs entgegen nimmt.

Code: Alles auswählen

int(''.join(map(str, [1,2,3,4])))
Oder das Ergebnis von map ... ;-)

Verfasst: Donnerstag 28. Januar 2010, 16:48
von derdon
... was wiederum eine Liste ist. itertools.imap geht auch, weil es ein Generator ist. Also reicht es doch, einfach zu sagen, dass str.join als ersten Parameter ein Iterable entgegen nimmt.