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:

Code: Alles auswählen

  for a, b in linkageGroups.items():
    print (a, b)
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.

Code: Alles auswählen

print ", ".join([a, c] + d)
Ü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.