Problem mit map()

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
mit
User
Beiträge: 285
Registriert: Dienstag 16. September 2008, 10:00

Hallo,
leider bekomme ich den folgenden Code nicht zu laufen:

Code: Alles auswählen

import math

def lg(a):
  return math.log(a)/math.log(2.0)

if __name__ == "__main__":
  temp = list("AXDA     .255 .245 .245 .255".split())
  s1 = temp[0]
  model1 = temp[1::]

  temp = list("CYEC .225 .275 .275 .225 ".split())
  s2 = temp[0]
  model2 = temp[1::]

  lod = map(lambda x: [lg(model1[x]/model2[x]) ], range(0,4))
  print lod
Beim ausführen bekomme ich diesen Fehler:

Code: Alles auswählen

Traceback (most recent call last):
  File "x.py", line 21, in ?
    lod = map(lambda x: [lg(model1[x]/model2[x]) ], range(0,4))
  File "x.py", line 21, in <lambda>
    lod = map(lambda x: [lg(model1[x]/model2[x]) ], range(0,4))
TypeError: unsupported operand type(s) for /: 'str' and 'str'
Was mache ich falsch?

Viele Grüße
Benutzeravatar
gkuhl
User
Beiträge: 600
Registriert: Dienstag 25. November 2008, 18:03
Wohnort: Hong Kong

Hallo, du versuchst hier zwei Strings durcheinander zu dividieren, was eben nicht geht. Du musst deine Strings in Floats umwandeln:

Code: Alles auswählen

In [5]: value = '255'

In [6]: type(value)
Out[6]: <type 'str'>

In [7]: value = float(value)

In [8]: type(value)
Out[8]: <type 'float'>
Grüße
Gerrit
BlackJack

@mit: *Die* Frage ist doch jetzt nicht wirklich ernst gemeint, oder? Das steht doch da ganz laut und deutlich: Man kann Zeichenketten nicht durcheinander teilen.

Und Du solltest vielleicht mal aufhören Perl Befehl für Befehl 1:1 in Python umsetzen zu wollen und besser das was das Perl-Skript macht in Python schreiben. Hier böte sich statt `map()` zum Beispiel eine "list comprehension" an, und mit `zip()` kann man sich die Indexe sparen.

Ausserdem solltest Du die Dokumentation zu `math.log()` nochmal genauer lesen -- Dein `lg()` lässt sich damit nämlich auch anders bewerkstelligen.

Was denkst Du was der `list()`-Aufruf nach dem `split()`\en der Zeichenketten bewirkt?
mit
User
Beiträge: 285
Registriert: Dienstag 16. September 2008, 10:00

Das mit float ist dumm gelaufen, ich habe nämlich gedacht, dass es .222 nach dem split ein float sein wird. Dies ist natürlich Unsinn.

Du hast recht, dass Perl Code 1:1 zu kopieren ist keine gute ist und ich mache es nur an den stellen wo ich es nicht weiss wie man es besser mit Python Befehlen machen kann.

Auf zip() wäre ich nicht gekommen, weil es ich es niemals benutzt habe.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Du scheint wohl an ganz vielen Stellen nicht zu wissen wie Python geht...

Das lambda sähe eher so aus:

Code: Alles auswählen

log = [lg(e1 / e2) for e1, e2 in zip(model1, model2)]
Das ist doch sinnlos:

Code: Alles auswählen

temp = list("AXDA     .255 .245 .245 .255".split())
Was ist das Ergebnis von ``.split()``? Ja, eine Liste. Was ist das Ergebnis von ``list(liste)`` - ja, eine Liste, mit den selben inhalt wie die vorherige.

``lg`` geht noch einfacher, weil ``math.log`` einen ``base`` Parameter hat:

Code: Alles auswählen

def lg(a):
    return math.log(a, 2)
Oh, es geht noch einfacher:

Code: Alles auswählen

from functools import partial
lg = partial(math.log, base=2)
Wobei dann irgendwie ``lg()`` nicht mehr so sinnvoll ist. Ich würde es aber eigentlich dann auch eher ``ld()`` nennen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
mit
User
Beiträge: 285
Registriert: Dienstag 16. September 2008, 10:00

@Leonidas: Danke für die Lösung, ich muss noch viel über Python lernen.

Leider verstehe ich nicht was dies tut:

Code: Alles auswählen

my $score = sum(map($lod[$_], split //,$a));
und habe es leider wieder versucht 1:1 zu kopieren, da ich es leider nicht besser weiss:

Code: Alles auswählen

score = sum(map(lambda x:[lod[x]], list(a)))
Aber ich bekomme diese Fehlermeldung "TypeError: list indices must be integers". Wie wandelt man am besten alle Elemente eines Arrays in Interger?
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Vielleicht magst Du erst einmal das Tutorial lesen? Damit dürften viele Deiner Fragen beantwortet werden.

Schnipsel wie

Code: Alles auswählen

map(int, '1 2 3'.split())
helfen Dir bei Deiner Frage nicht wirklich weiter, ohne, dass Du a) ein bißchen belesener bist und uns b) sagst worum es überhaupt geht, denn ich bin mir fast sicher, dass es einfache und effiziente Lösungen für Dein Problem gibt.

edit: Was ist lod?

Gruß,
Christian
mit
User
Beiträge: 285
Registriert: Dienstag 16. September 2008, 10:00

Sorry habe vergessen den ganzen code zu posten. Ich glaube ich habe mich falsch ausgedrückt, denn ich war nach der suche, wie man jedes Element eines Arrays in jeweils ein Integer Wert umwandelt, d.h. dass Array genau so viele Elemente beinhaltet wie vorher, aber diesmal vom Typ Integer.

Code: Alles auswählen

import string, math

def lg(a):
    return math.log(a, 2)

if __name__ == "__main__":
  temp = list("AXDA     .255 .245 .245 .255".split())
  s1 = temp[0]
  model1 = temp[1::]

  temp = list("CYEC .225 .275 .275 .225 ".split())
  s2 = temp[0]
  model2 = temp[1::]

  lod = = [lg(float(e1) / float(e2)) for e1, e2 in zip(model1, model2)]
  print lod 

  a = 'aagcaaatccgcgataaaattgccttggggcgtataaaagg'
  a = a.translate(string.maketrans('acgtACGT', '01230123'))
  print a
  a = map(int, a.split())
  print a
  score = sum(map(lambda x:[lod[x]], list(a)))
  print score 
Score sollte 1.15346400039175 betragen.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

19.36...? ;-)

Also mal als Hilfe:

- math.log erwartet kein Keyword, also wird aus Leonidas Beispiel:

Code: Alles auswählen

from functools import partial
lg = partial(math.log, 2)
- Was soll das?

Code: Alles auswählen

temp = list("AXDA     .255 .245 .245 .255".split())
.split() macht aus dem String eine Liste. list() anzuwenden ist doppelgemoppelt.
- Wozu die temps? Es geht auch

Code: Alles auswählen

dat1 = "AXDA     .255 .245 .245 .255".split()
  s1 = dat1[0]

  dat2 = list("CYEC .225 .275 .275 .225 ".split())
  s2 = dat2[0]

  lod = [lg(float(e1) / float(e2)) for e1, e2 in zip(dat1[1:], dat2[1:])]
wobei sich meinereiner fragt, wozu s1 und s2 gut sind und ob es nicht doch ein wenig deutlicher geht. Aber dazu solltest Du vielleicht erst einmal das Tutorial und insb. den Abschnitt zu Funktionen lesen. Will nicht besserwisserisch sein: Das ist ganz ernst gemeint.
- Das Erstellen und Anwenden der Translationtable würde ich trennen. Und wenn Du ein dezentes .upper() auf Deine Sequenz anwendest, kannst Du auf die Kleinbuchstaben verzichten und dennoch jeden Input verwursten.
- map(int, a.split()) ist - mit Verlaub - Blödsinn. Was ist denn a? Ein String ohne Leerzeichen. Und was macht split() damit?
Was Du willst ist eine Liste von Integern. z. B. so:

Code: Alles auswählen

a = [int(x) for x in a]
wobei, ... Na ja, Du liest das Tutorial, oder? ;-)
-

Code: Alles auswählen

score = sum((lod[x] for x in a))
Kommentar: Das Tutorialkapitel zum Thema dicts ist auch lesenswert ;-). Damit könntest Du Zuordnungstabellen etwas einfacher gestalten.

HTH
Christian
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Oh, ich sehe gerade Deine score-Angabe: Bist Du Dir sicher?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

CM hat geschrieben:- math.log erwartet kein Keyword, also wird aus Leonidas Beispiel:

Code: Alles auswählen

from functools import partial
lg = partial(math.log, 2)
Dann wird aber ein Schuh draus, da ``partial`` die Parameter von links nach rechts einsetzt, und man damit die partielle Funktion ``math.log(2, [bases])`` bekommt - eher nicht der Logarithmus von 2. Schade, das hätte auch so gut funktionieren können.

Somit muss man das so lösen:

Code: Alles auswählen

lg = lambda x: math.log(x, 2)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Ups, ich Blindfisch. Tja, dann stimmt auch das Ergebnis .... :oops:

Danke!
mit
User
Beiträge: 285
Registriert: Dienstag 16. September 2008, 10:00

Vielen Dank.
Antworten