Seite 1 von 1
dictonaries problem
Verfasst: Dienstag 29. Dezember 2009, 04:03
von mit
Hallo,
ich habe folgende Eingabe Datei:
Code: Alles auswählen
G|G0024s00480|s_24|G0024s00480.1|438189|438579|-1
G|G0024s00240|s_24|G0024s00240.1|14401|16599|1
G|G0022s00500|s_22|G0022s00500.1|990172|990304|1
G|G0023s00620|s_23|G0023s00620.1|708242|709405|-1
Und versuche die Daten aus der Datei in dictonary zu speichern
Code: Alles auswählen
{ 's_22': {'G0022s00500.1': ['990172', '990304', '1']},
's_23': {'G0023s00620.1': ['708242', '709405', '-1']},
's_24': {'G0024s00240.1': ['14401', '16599', '1']}}
Leider wird die erste Zeile aus der Datei in dictonary durch die zweite Zeile überschrieben und ich erhalte nicht die gewünschte Ausgabe:
Code: Alles auswählen
{ 's_22': {'G0022s00500.1': ['990172', '990304', '1']},
's_23': {'G0023s00620.1': ['708242', '709405', '-1']},
's_24': {'G0024s00240.1': ['14401', '16599', '1']},
'G0024s00480.1': ['438189','438579','-1']}}
Ich habe dieses skript geschrieben:
Code: Alles auswählen
import pprint
def retrieveIds():
f = open("a.txt","r")
linkageGroups = {}
while True:
line = f.readline().rstrip()
if not line:
break
line = line.split("|")
#G|G0024s00480|s_24|G0024s00480.1|438189|438579|-1
#0 1 2 3 4 5 6
linkageId = line[2] # s_24
gId = line[3] # G0024s00240.1
start = line[4] # 14401
end = line[5] # 16599
strand = line[6] # -1
aGroup = {gId:[start, end, strand]}
linkageGroups[linkageId] = aGroup
pp = pprint.PrettyPrinter(indent=2)
pp.pprint(linkageGroups)
if __name__ == '__main__':
seqLen = 0
firstSeqRead = False
setNewLine = False
retrieveIds()
Was mache ich falsch?
Viele Grüße
Verfasst: Dienstag 29. Dezember 2009, 06:08
von cofi
Deine 3. Zeile ist eben kein brauchbarer Dictionary Key, da er mehrfach vorkommt.
Je nachdem was du benoetigst, kannst du dein Dict von Dicts in ein Dict von Listen von Dicts abaendern oder ein Multidict benutzen, aber beschreib am besten erstmal was genau du benoetigst.
Verfasst: Dienstag 29. Dezember 2009, 08:47
von mit
s_24 kommt in der Datei zweimal vor und deshalb wollte ich zwei dicts erstellen um diese Information zu speichern:
G0024s00480.1|438189|438579|-1
G0024s00240.1|14401|16599|1
wobei:
G0024s00480.1
G0024s00240.1
als Schlüssel dienen sollten.
Später wollte ich die folgende Ausgabe erhalten:
s_22, G0022s00500.1, 990172, 990304, 1
s_23, G0023s00620.1, 708242, 709405, -1
s_24, G0024s00240.1, 14401, 16599, 1
s_24, G0024s00480.1, 438189, 438579, -1
Und auf die 3 letzten werte zugreifen können.
Leider weiss ich nicht wie man es am besten macht.
Verfasst: Dienstag 29. Dezember 2009, 09:22
von Darii
mit hat geschrieben:s_24 kommt in der Datei zweimal vor und deshalb wollte ich zwei dicts erstellen um diese Information zu speichern:
Was macht das für einen Sinn zwei Dicts mit jeweils einem Schlüssel zu erstellen? Nimm doch ein Dictionary jeweils mit den Werten als Schlüssel.
Das ganze Packst du dann noch in ein 2. Dictionary und fertig(ich nehme für sowas immer ein
defaultdict).
Code: Alles auswählen
from collections import defaultdict
...
def retrieveIds():
...
linkageGroups = defaultdict(dict)
for line in f:
linkageId, gId, start, end, strand = line.rstrip().split("|")[2:]
linkageGroups[linkageId][gId] = [start, end, strand]
PS: Es ist übrigens immer nett, die Datei hinterher zu
schließen, wenn man fertig ist.
Verfasst: Mittwoch 30. Dezember 2009, 03:10
von mit
Danke es funktioniert, aber ich noch zwei Fragen:
1.) Wie bekommt man folgende Ausgabe?
s_22, G0022s00500.1, 990172, 990304, 1
s_23, G0023s00620.1, 708242, 709405, -1
s_24, G0024s00240.1, 14401, 16599, 1
s_24, G0024s00480.1, 438189, 438579, -1
2.) Wie könnte man z.B. in einer for-Schleife eine if-Anweisung nutzen um "-1" abfangen und z.B. auf diese Werte zugreifen 708242 und 709405?
Der aktuelle Kode sieht wie folgt aus:
Code: Alles auswählen
import pprint
from collections import defaultdict
def retrieveIds():
f = open("a.txt","r")
linkageGroups = defaultdict(dict)
for line in f:
#G|G0024s00480|s_24|G0024s00480.1|438189|438579|-1
#0 1 2 3 4 5 6
linkageId, gId, start, end, strand = line.rstrip().split("|")[2:]
linkageGroups[linkageId][gId] = [start, end, strand]
pp = pprint.PrettyPrinter(indent=2)
pp.pprint(linkageGroups)
print "\n\n"
print (linkageGroups)
print "\n\n"
print (linkageGroups["s_24"]["G0024s00480.1"])
print (linkageGroups["s_24"]["G0024s00480.1"][0])
print (linkageGroups["s_24"])
if __name__ == '__main__':
retrieveIds()
Und die Eingabe Datei sieht wie folgt aus:
Code: Alles auswählen
G|G0024s00480|s_24|G0024s00480.1|438189|438579|-1
G|G0024s00240|s_24|G0024s00240.1|14401|16599|1
G|G0022s00500|s_22|G0022s00500.1|990172|990304|1
G|G0023s00620|s_23|G0023s00620.1|708242|709405|-1
Verfasst: Mittwoch 30. Dezember 2009, 09:36
von snafu
Was für eine Art von Daten ist das? Für Python gibt es viele Zusatzmodule im Internet, auch für wissenschaftliche Zwecke. Gut möglich, dass dir so etwas besser helfen könnte.
Verfasst: Mittwoch 30. Dezember 2009, 09:52
von Darii
mit hat geschrieben:1.) Wie bekommt man folgende Ausgabe?
s_22, G0022s00500.1, 990172, 990304, 1
s_23, G0023s00620.1, 708242, 709405, -1
s_24, G0024s00240.1, 14401, 16599, 1
s_24, G0024s00480.1, 438189, 438579, -1
Indem du die einzelnen Einträge mit einer
for-Schleife durchgehst und dann deine Ausgabe machst
Verfasst: Mittwoch 30. Dezember 2009, 11:44
von mit
Leider gibt es dafür kein Python Modul und ich bin mit der folgenden for-Schleife gescheitert:
und erhalte diese Ausgabe:
Code: Alles auswählen
('s_24', {'G0024s00240.1': ['14401', '16599', '1'], 'G0024s00480.1': ['438189', '438579', '-1']})
('s_22', {'G0022s00500.1': ['990172', '990304', '1']})
('s_23', {'G0023s00620.1': ['708242', '709405', '-1']})
Wie muss die for-Schleife aussehen?
Verfasst: Mittwoch 30. Dezember 2009, 12:02
von Darii
mit hat geschrieben:Leider gibt es dafür kein Python Modul
Natürlich nicht, warum sollte es auch für dein spezielles Problem ein extra Modul in der Standardbibliothek geben?
und ich bin mit der folgenden for-Schleife gescheitert:
Nein du bist nicht gescheitert, du hast einfach nur das Beispiel aus dem Tutorial abgeschrieben und dich gewundert warum das nicht das ist was du willst. Ich helfe gerne aber ein bisschen Eigeninitiative erwarte ich auch. Zum Lösung vorkauen ist mir meine Zeit zu schade und du lernst dabei auch nichts.
Verfasst: Mittwoch 30. Dezember 2009, 12:30
von mit
Habe es mit zwei for-Schleifen geschafft
Code: Alles auswählen
for a, b in linkageGroups.items():
for c, d in b.items():
print a + ", " + c + ", " + d[0] + ", " + d[1] + ", " + d[2]
Ist dies eine gute Lösung?
Verfasst: Mittwoch 30. Dezember 2009, 13:41
von Darii
Ja, allerdings würde dir von solch kryptischen Variablennamen abraten. Zu der Ausgabe selbst, wenn man irgendwas stupide wiederholen muss(in deinem Fall die ganzen ", ") ist das immer ein Hinweis darauf, dass es auch kürzer geht.
Übrigens sind dictionaries unsortiert wenn man z.B. nach Schlüsseln sotieren will, wäre ein
Code: Alles auswählen
for key in sorted(dictionary):
print key, dictionary[key]
am einfachsten.
Verfasst: Mittwoch 30. Dezember 2009, 17:00
von BlackJack
@Darii: Von der Standardbibliothek war ja nicht die Rede. Für viele Formate gibt es halt schon Module von Drittanbietern. Speziell wenn man nicht der erste ist, der sich mit einem bestimmten Format befasst.
Verfasst: Mittwoch 30. Dezember 2009, 17:18
von Darii
BlackJack hat geschrieben:@Darii: Von der Standardbibliothek war ja nicht die Rede. Für viele Formate gibt es halt schon Module von Drittanbietern. Speziell wenn man nicht der erste ist, der sich mit einem bestimmten Format befasst.
Siehe Kontext meines Satzes. Es ging um den Umgang mit Schleifen.
Verfasst: Mittwoch 30. Dezember 2009, 18:04
von BlackJack
@Darii: Wenn Du's darauf beschränken möchtest -- für mich ging's hier um das Verarbeiten dieser Daten.
Verfasst: Mittwoch 30. Dezember 2009, 23:00
von snafu
Ich habe das in Bezug zu meiner Frage gesehen. Dummerweise ist die Antwort leider nicht auf das Wesentliche ("welche Art Daten?") eingangen, sondern hat sich auf ein "nee, gibt's nicht..." beschränkt. Da kann man dann natürlich auch nicht mehr viel machen.