Arbeit mit Listen

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
silky vanilla
User
Beiträge: 51
Registriert: Donnerstag 3. Mai 2007, 09:46

Ich habe mal wieder ein Problem.
Ich habe eine grosse Datei, aus der ich die Elemente bzw. Eintraege aus den Spalten 1 und 2 in eine Liste ueberfuehren moechte. Es koennen jedoch gleiche Elemente jeweils in Spalte 1 und auch in Spalte 2 auftreten. In der Liste soll jedes Element nur einmal vorhanden sein.
Anschliessend moechte ich aus der neu erzeugten Liste immer genau zwei Elemente gegenueberstellen. Zu beachten ist, dass die Elemente voneinander verschieden sein muessen und dass sie in dieser Kombination auch noch nicht aufgetreten sind (Hin- u. Rueckrichtung ist zu beachten:
A - B == B - A

Bei der Umsetzung habe ich jedoch einige Probleme

Code: Alles auswählen

inp = open('test_interaktionen','r')

##header = inp.readline()

all_genes =[]
for line in inp:
    data = line.split()
    data[0] = list(data[0])
    data[0].append(all_genes)
Es gibt mir eine leere Liste fuer all_genes zurueck :?:
Zizibee
User
Beiträge: 229
Registriert: Donnerstag 12. April 2007, 08:36

Das liegt wohl daran, dass du versuchst "all_genes" in "data[0]" zu schreiben, anstatt anderst herum.
Richtig lauten müsst es meiner Meinung nach:

Code: Alles auswählen

all_genes.append(data[0])
silky vanilla
User
Beiträge: 51
Registriert: Donnerstag 3. Mai 2007, 09:46

Ups :lol: ok...Kavaliersdelikt

Aber hat jemand eine Idee, wie ich umsetzen kann, dass in der Liste jedes Element aus beiden Spalten nur einmal auftritt?
silky vanilla
User
Beiträge: 51
Registriert: Donnerstag 3. Mai 2007, 09:46

Hier mein Code Schnipsel bis jetzt

Code: Alles auswählen

inp = open('test_interaktionen','r')

##header = inp.readline()

all_genes =[]
for line in inp:
    data = line.split()
    data[0] = list(data[0])
    if data[0] != all_genes:
        all_genes.append(data[0])
    data[1] = list(data[1])
    if data[1] != all_genes:
        all_genes.append(data[1])
Wenn ich diese if Anweisungen weglasse und nur anhaenge, kommen natuerlich gleiche Element in meiner Liste auch mehrfach vor.
Mit if Anweisung macht es aber auch nicht das, was ich moechte...
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Wie wäre es so?

Code: Alles auswählen

if data[0] not in all_genes:
MfG
HWK
silky vanilla
User
Beiträge: 51
Registriert: Donnerstag 3. Mai 2007, 09:46

oh cool, vielen Dank.
Ich dachte

Code: Alles auswählen

if data[0] != all_genes
waere das gleiche wie

Code: Alles auswählen

if data[0] not in all_genes
aber scheinbar ja nicht.

Jetzt habe ich also meine "bereinigte" Liste, wie kann ich nun eine Randomisierung aller Werte zu einer Gegenueberstellung zweier Werte umsetzen? Wenn ich es in einer schleife machen moechte, wie kann ich die dann beenden, wenn ich doch alle moeglichen Gegenueberstellungen haben moechte?
silky vanilla
User
Beiträge: 51
Registriert: Donnerstag 3. Mai 2007, 09:46

Hier wieder ein Code Schnipsel, der zweite Teil ab
neg_edges
funktioniert jedoch nicht so, wie ich das moechte

Code: Alles auswählen

from random import choice

inp = open('test_interaktionen','r')

##header = inp.readline()

all_genes =[]
for line in inp:
    data = line.split()
    data[0] = list(data[0])
    if data[0] not in all_genes:
        all_genes.append(data[0])
    data[1] = list(data[1])
    if data[1] not in all_genes:
        all_genes.append(data[1])

neg_edges = set()
while data in all_genes:
    itter = 0
    data = tuple(sorted((choice(all_genes), choice(all_genes))))
    while data in neg_edges \
        data[0] == data[1]:
        data = tuple(sorted((choice(all_genes), choice(all_genes))))
        itter +=1
    neg_edges.add(data)
Tips :?:
BlackJack

Das kompiliert nicht, da ist ein Syntaxfehler drin. In Zeile 21/22 fehlt mindestens ein ``and`` oder ein ``or``.

Vielleicht solltest Du mal das Tutorial durcharbeiten und die Grundlagen lernen. Auch die erste Schleife sieht eigenartig und umständlich aus. Da wäre zum Beispiel ein `set()` auch effizienter als der ``in``-Test auf einer Liste.

Die zweite Schleife sieht mir sehr nach einer Endlosschleife aus. Irgendwann sind in `neg_edges` alle Kombinationen enthalten und die innere ``while``-Schleife wird nie mehr verlassen, wenn das ein ``or`` sein sollte, was dort in der Bedingung fehlt.

Das ist auch extrem ineffizient, weil je mehr Kombinationen in `neg_edges` stehen, um so länger dauert es zufällig eine zu finden, die noch nicht enthalten ist. Wenn da *alle* Kombinationen drin sein sollen, dann generiere die doch einfach systematisch. Stell Dir vor Du hättest eine Liste mit ein paar Elementen, Zettel und Stift und solltest solche paare bilden. Wie würdest Du vorgehen? Das musst Du dann nur noch in ein Programm verpacken.
silky vanilla
User
Beiträge: 51
Registriert: Donnerstag 3. Mai 2007, 09:46

Die Variante mit dem set() ist wirklich besser, denn dann werden ja alle Elemente, die mehrmals vorkommen automatisch geloescht.
Jetzt hab ich also ein set, welches alle Eintraege aus Spalte 1 und 2 enthaelt.
Nun hab ich das set einfach wieder in ein Liste umgewandelt, weil sich sicher damit besser arbeiten laesst.
Wenn ich die Elemente nicht zufaellig waehlen lasse, sondern Element 1 aus der Liste mit allen verbleibenden kombiniere, dann Element 2 und mit allen ausser sich selbst kombiniere (wobei hier ausgeschlossen werden muss, dass diese Kombination schon vorkommt) usw., ist der Weg umstaendlich?
Jedenfalls wuerde ich dann der endlosen while Schleife und der Ineffizienz bei schon vielen gefundenen Kombinationen aus dem Weg gehen.
Gibt es dafuer eine Funktion wie bei random choice?
BlackJack

Bei den Kombinationen müsste eine einfache zweifach verschachtelte Schleife und wieder ein `set()` ausreichen (ungetestet):

Code: Alles auswählen

def main():
    all_genes = set()
    for line in lines:
        data = line.split()
        for gene in data[:2]:
            all_genes.add(tuple(gene))
    
    neg_edges = set()
    for gene1 in all_genes:
        for gene2 in all_genes:
            if gene1 != gene2:
                if gene1 > gene2:
                    gene1, gene2 = gene2, gene1
                neg_edges.add((gene1, gene2))
silky vanilla
User
Beiträge: 51
Registriert: Donnerstag 3. Mai 2007, 09:46

Naja, dass ist noch nicht ganz das, was ich wollte.
Nun wir ja nur der erste Eintrag aus der Liste mit allen anderen kombiniert, die anderen Eintraege jedoch nicht. Aber mit ein paar kleinen Veraenderungen funktioniert auch das jetzt.
Danke fuer die Hilfe.

Code: Alles auswählen

all_genes =set()
for edge in pos:
    all_genes.add(edge[0])
    all_genes.add(edge[1])
all_genes = list(all_genes)


neg_edges = set()
for gene1 in all_genes:
    for gene2 in all_genes:
        if gene1 != gene2:
            edge = tuple(sorted((gene1, gene2)))
            if edge not in pos:
                neg_edges.add(edge)
Antworten