2016-08-08 46 views
1

Ich habe eine Liste, die so etwas geht, und neuer Inhalt wird in einer Schleife hinzugefügt.Vergleichen Sie nur einen Teil von zwei der drei Elemente in Triple

list = [("banana", "a", 0), ("banana", "b", 1), ("coconut", "a", 2)] 

In der Schleife Ich möchte Elemente hinzufügen wie folgt:

list.append(("strawberry", "b", 4)) 

aber dies kann nicht auftreten, wenn das erste und das zweite Element in dieser Reihenfolge zusammen bereits in der Liste enthalten ist. Zum Beispiel kann die folgende Liste nicht zu list hinzugefügt werden, da der erste Artikel bereits "Banane" zusammen mit "a" enthält.

("banana", "a", 5) # Should NOT be appended 
("banana", "c", 6) # SHOULD be appended 
("strawberry", "a", 7) # SHOULD be appended 

In einer regelmäßigen Liste wir Duplikate so etwas wie die folgenden tun würden zu vermeiden:

if not item in list: 
    list.append(item) 

aber beachten Sie, dass mein Fall nur teilweise doppelte mit sich bringt, dh die ersten beiden Elemente nicht zwischen identisch sein können Unterlisten.

Ich bin auf der Suche nach einer sehr effizienten Lösung, weil die Liste Tausende von Elementen enthalten kann.

+1

Ich denke, dass du eigentlich "liste.append" (("Erdbeere", "b", 4)) '(besser) oder' liste.extend ([("Erdbeere", "b", 4)]) 'statt' liste.extend (("erdbeere", "b", 4)) ' – janbrohl

+0

@jankrohl Sie haben Recht! Bearbeitet. –

Antwort

0

Ich würde einen Wörterbuch für diese Art der Datenkoppelstruktur sehr empfehlen, zusammen mit O (1) Look-up-Zeiten, werden Sie auch ein besseres Design implementieren.Sie können jedoch dieses mit dem aktuellen Datenstruktur zu tun mit der folgenden:

Beispielausgabe:

Mit aktueller Struktur:

l = [ ("banana", "a", 0), ("banana", "b", 1), ("coconut", "a", 2) ] 
items_to_add = [("banana", "a", 5), ("banana", "c", 6), ("strawberry", "a", 7)] 

for item_to_add in items_to_add: 
    if not item_to_add[:2] in [i[:2] for i in l]: 
     l.append(item_to_add) 
print l 
>>> [('banana', 'a', 0), ('banana', 'b', 1), ('coconut', 'a', 2), 
('banana', 'c', 6), ('strawberry', 'a', 7)] 

Andere weisen, können Sie einen Wörterbuch verwenden (ausschließen Sie Ihre zwei ersten Elemente zu Ihrem Schlüssel):

Mit Wörterbuch:

d = { ("banana", "a") : 0, ("banana", "b") : 1, ("coconut", "a") : 2 } 
items_to_add = [("banana", "a", 5), ("banana", "c", 6), ("strawberry", "a", 7)] 

for item_to_add in items_to_add: 
    key = item_to_add[:2] 
    value = item_to_add[-1] 
    if not key in d: 
     d[key] = value 
print d 
>>> {('coconut', 'a'): 2, ('strawberry', 'a'): 7, ('banana', 'c'): 6, 
('banana', 'a'): 0, ('banana', 'b'): 1} 

Ein Wörterbuch funktioniert sehr gut in diesem Szenario wie Sie versuchen, Eigenschaften von Schlüssel/Wert Datenstruktur zu nutzen. Eindeutige Schlüssel sind sichergestellt, und dies wird auch die effizienteste Route sein.

0

wäre eine zeiteffiziente Lösung, die eine set mit hinzugefügten Elemente

li = [("banana", "a", 0), ("banana", "b", 1), ("coconut", "a", 2)] 
se= set(t[:2] for t in li) 

add=[ 
("banana", "a", 5), # Should NOT be appended 
("banana", "c", 6), # SHOULD be appended 
("strawberry", "a", 7) # SHOULD be appended 
] 

for t in add: 
    ct=t[:2] 
    if ct not in se: 
     li.append(t) 
     se.add(ct) 

danach zu halten sein, li[('banana', 'a', 0), ('banana', 'b', 1), ('coconut', 'a', 2), ('banana', 'c', 6), ('strawberry', 'a', 7)]

1

ist, können Sie das Vorhandensein einer neuen Sache überprüfen mit

#check for every item if newItem matches an Item in the list 
if not any(True for item in list if newItem[:2]==item[:2]): 
    # add your newItem 
1

Sie können Tupel als Schlüssel in einem Wörterbuch verwenden:

fruits = { 
    ('banana', 'a'): 0, 
    ('banana', 'b'): 1, 
    ('coconut', 'a'): 2, 
} 

Dann können Sie einfach überprüfen, ob (item[0], item[1]) bereits im Wörterbuch ist:

item = ('strawberry', 'b', 4) 
if (item[0], item[1]) not in fruits: 
    fruits[item[0], item[1]] = item[2] 

Wenn Sie Auftrag erhalten möchten, können Sie OrderedDict anstelle des integrierten Wörterbuch verwenden können.

Dies vermeidet die Verwendung von mehr Speicher zum Speichern einer Reihe von Schlüsseln und ist auch effizient in Bezug auf die Suche.

+0

Und wie könnte ich effizient die Schlüssel von einem neuen Element mit allen Schlüsseln aus der Liste vergleichen? (Ich bin nicht in Python kompetent ...) –

+0

Ich habe meine Antwort aktualisiert, um ein Beispiel zu geben :) – Karin

1
data = [("banana", "a", 0), ("banana", "b", 1), ("coconut", "a", 2)] 
items = [("banana", "a", 5), ("banana", "c", 6), ("strawberry", "a", 7)] 

for item in items: 
    if item[:2] not in map(lambda x: x[:2], data): 
     data.append(item) 

Ausgang:

[('banana', 'a', 0), 
    ('banana', 'b', 1), 
    ('coconut', 'a', 2), 
    ('banana', 'c', 6), 
    ('strawberry', 'a', 7)]