Listen in einem verschachtelten defaultdict durchsuchen

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,
wie würde man am besten Listen in einem verschachtelten defaultdict durchsuchen (siehe Code unten) mit folgenden Bedingungen:

- 7 aus r[6] ist korrekt weil für "5" und "6" aus r[8] beide unterschiedliche Buchstaben in r[7] haben. Auch korrekt ist 9 aus r[6]
- 8 aus r[6] würde korrekt sein weil für "5" und "6" aus r[8] beide unterschiedliche Buchstaben in r[7] haben, aber ist nicht im Bereich von 200000 bis 2000000.
- 10 aus r[6] ist zu Ignorieren weil für "5" und "6" aus r[8] ein 'X' in r[7] vorhanden ist
- 14 aus r[6] ist zu Ignorieren weil für "5" und "6" aus r[8] beide 'G' in r[7] haben

und als Ergebnis folgendes ausgibt '"Test", "A", "B01", 828288, 7'?

Code: Alles auswählen

from collections import defaultdict

class Test():

    def __init__(self, s_id, s_type_id, pos, chr, name_id):
        self.s_id = s_id
        self.s_type_id = s_type_id
        self.pos = pos
        self.chr = chr
        self.name_id = name_id

if __name__ == "__main__":

    r = [["Test", "A", "B01", 828288,  1, 1,   7, 'C', 5],
         ["Test", "A", "B01", 828288,  1, 1,   7, 'T', 6],
         ["Test", "A", "B01", 171878,  3, 7,   8, 'C', 5],
         ["Test", "A", "B01", 171878,  3, 7,   8, 'T', 6],
         ["Test", "A", "B01", 871963,  3, 8,   9, 'A', 5],
         ["Test", "A", "B01", 871963,  3, 8,   9, 'G', 6],
         ["Test", "A", "B01", 1932523, 1, 9,  10, 'T', 4],
         ["Test", "A", "B01", 1932523, 1, 9,  10, 'A', 5],
         ["Test", "A", "B01", 1932523, 1, 9,  10, 'X', 6],
         ["Test", "A", "B01", 667214,  1, 11, 14, 'T', 4],
         ["Test", "A", "B01", 667214,  1, 11, 14, 'G', 5],
         ["Test", "A", "B01", 667214,  1, 11, 14, 'G', 6]]

    s = defaultdict(lambda: defaultdict(lambda: defaultdict(list)))
    
    for i in r:
        s[r[0]][r[1]][r[2]].append(Test(r[6], r[4], r[3], r[7], r[8]))
    print s
Oder gibt es eine bessere Datenstruktur um dieses Problem zu lösen?

Vielen Dank im voraus.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

mit hat geschrieben:Oder gibt es eine bessere Datenstruktur um dieses Problem zu lösen?
Wahrscheinlich schon, das hängt natürlich vom konkreten Problem ab. Wenn du die Daten vernünftig Unterteilst, dann wird sicher auch die Suche einfacher. Möglicherweise bietet sich auch eine Datenbank an. Auf jeden Fall finde ich drei Ebenen Dictionaries zu unübersichtlich.
Das Leben ist wie ein Tennisball.
mit
User
Beiträge: 285
Registriert: Dienstag 16. September 2008, 10:00

Datenbank würde ich am liebsten vermeiden und im Moment verschachtelten defaultdict ist das Beste was ich ausdenken konnte.
BlackJack

@mit: Also ich finde das auch zu kompliziert. Vor allem weil die Datestruktur diese Suche die Du da vorhast überhaupt nicht unterstützt. Dieses verschachtelte Wörterbuch hat im Grunde doch gar nichts mit der Fragestellung zu tun weil die Bedingungen alle auf Werten definiert sind die *nicht* in den Schlüsseln, sondern ausschliesslich in den Werten auf der tiefsten Verschachtelungsebene greifen.

Und irgendwie schreit mir das auch sehr nach Datenbankabfrage.
Ene Uran
User
Beiträge: 125
Registriert: Sonntag 17. September 2006, 20:14
Wohnort: Hollywood

Eine "named tuple" waere ne Moeglichkeit, hier ein Beispiel:

Code: Alles auswählen

from collections import namedtuple
import pprint

# potentially from a CSV file:
# name,age,weight lines
data_str = '''\
Sarah Gellar,26,121
Alec Baldwin,47,214
Mandy Moore,22,135
Matthew Goode,29,167
Amanda Bynes,19,112
James Kirk,24,175
'''

# create a list of [name, age, weight] lists
data_list = [line.split(',') for line in data_str.split('\n') if line]

# Star behaves like a class
Star = namedtuple('movie_star', 'name age weight')

# create a list of instances
star_list = [ Star(name, int(age), int(weight))\
             for name, age, weight in data_list]

pprint.pprint(star_list)

print('-'*65)
print(star_list[1])
print(star_list[1].name)

print('-'*65)
print(star_list[1]._fields)

print('-'*65)
pounds = 150
print('Show all the movie stars weighing over {} lbs:'.format(pounds))
for star in star_list:
    if star.weight > pounds:
        print('{} weighs {} lbs'.format(star.name, star.weight))

''' my result >>>
[movie_star(name='Sarah Gellar', age=26, weight=121),
 movie_star(name='Alec Baldwin', age=47, weight=214),
 movie_star(name='Mandy Moore', age=22, weight=135),
 movie_star(name='Matthew Goode', age=29, weight=167),
 movie_star(name='Amanda Bynes', age=19, weight=112),
 movie_star(name='James Kirk', age=24, weight=175)]
-----------------------------------------------------------------
movie_star(name='Alec Baldwin', age=47, weight=214)
Alec Baldwin
-----------------------------------------------------------------
('name', 'age', 'weight')
-----------------------------------------------------------------
Show all the movie stars weighing over 150 lbs:
Alec Baldwin weighs 214 lbs
Matthew Goode weighs 167 lbs
James Kirk weighs 175 lbs
'''


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

Welche Datenbank würde für dieses Problem geeignet sein?
Antworten