2016-07-30 24 views
2

Ich habe zwei Listen gleicher Länge:Wie Elemente in einer Liste basierend auf einer anderen Liste in Python, ohne Schleifen zu entfernen?

list_a = ['a','b','c','d'] 
list_b = [-6.3, 3.1, 0.5, 4.1] 

Ich möchte die Elemente entfernen < 0,7 in list_b, und gleichzeitig die entsprechenden Elemente aus list_a entfernen, das heißt

list_a_2 = ['b','d'] 
list_b_2 = [3.1, 4.1] 

Ich weiß, dass die zweite Liste ,

list_b_2 = [item for item in hem if item > 0.7]. 

Aber gibt es eine Liste denk Weg list_a_2 zu bekommen, ohne Loops?

+0

Ohne Schleifen zu verwenden? Nicht wirklich ... Eine Schleife wird wahrscheinlich irgendwo benutzt werden, auch wenn Sie sie nicht explizit schreiben –

+0

Versuchen Sie, beide Schleifen gleichzeitig zu durchlaufen, filtern Sie qualifizierende Elemente in eine Ergebnisliste (oder zwei). – GManNickG

Antwort

6

Eine Möglichkeit ist zip zu verwenden:

list_a_2, list_b_2 = zip(*[(a, b) for a, b in zip(list_a, list_b) if b > 0.7])  
list_a_2 
# ('b', 'd') 

list_b_2 
# (3.1, 4.1) 

Wenn eine for-Schleife besser geeignet ist, können Sie zwei leere Listen erstellen und bedingt die Werte zu ihnen anhängen:

list_a_2, list_b_2 = [], [] 
for a, b in zip(list_a, list_b): 
    if b > 0.7: 
     list_a_2.append(a) 
     list_b_2.append(b) 

list_a_2 
# ['b', 'd'] 

list_b_2 
# [3.1, 4.1] 
+0

Danke für die Hilfe. –

+0

Verwenden Sie einen Generatorausdruck, um es nett zu einem faulen zu machen! –

1

Ohne explizite Schleifen , schaffen beide? Sicher, wenn wir ein temporäres Objekt verwenden:

list_a = ['a','b','c','d'] 
list_b = [-6.3, 3.1, 0.5, 4.1] 
tmp = zip(a, b) 
list_a_2 = [x[0] for x in tmp if x[1] > 0.7] 
list_b_2 = [x[1] for x in tmp if x[1] > 0.7] 
del tmp 

Aber mit einer tatsächlichen for-Schleife wird ein bisschen offensichtlicher sein:

for idx, value in enumerate(list_b): 
    if value =< 0.7: 
     list_a.pop(idx) 
     list_b.pop(idx) 

Aber du bist die Verwaltung noch zwei Listen für die Zuordnung (im Wesentlichen) Schlüssel zu Werten. Dies ist, was ein Wörterbuch ist! Konsolidieren jene Liste und erstellen Sie Ihre Teilmenge mit einem gewissen Wörterbuch Verständnis:

{x:y for x, y in zip(list_a, list_b) if y > 0.7} 
+0

Die 3 Methoden sind inspirierend! Vielen Dank. –

+0

Ich fand, dass ich durch die Verwendung von for-Schleife mit einer langen Liste von 3.828 Elementen nicht sofort alle Elemente <0,7 entfernen konnte. Jedes Mal, wenn ich den Code ausführte, ging die Länge der Listen zurück. Nur nach viermaligem Laufen wird die ganze Zahl von weniger als 0,7 hinausgeschmissen. Könnte ich dieses Problem vermeiden? –

+1

Es ist keine gute Idee, ein Element aus einer Liste zu entfernen, während man es durchläuft, was als solches ein Problem verursachen würde. Jedes Mal, wenn Sie das Element entfernen, ändert sich die Länge der Liste und Sie springen tatsächlich über ein Element, ohne es zu überprüfen. – Psidom

0

Wenn Sie wirklich Schleifen vermeiden wollen Sie eine rekursive Funktion verwenden können:

def unnecessarily_recursive_function(list_a,list_b): 
    try: 
     a = list_a.pop(0) 
     b = list_b.pop(0) 
     tmp_a, tmp_b = unnecessarily_recursive_function(list_a,list_b) 
     if b < 0.7: 
      return [a] + tmp_a, [b] + tmp_b 
     else: 
      return tmp_a, tmp_b 
    except IndexError: 
     return [],[] 

, die Sie anrufen können, wie:

list_a, list_b = unnecessarily_recursive_function(list_a, list_b) 

Beachten Sie, dass dies ein wirklich schlechter Grund ist, eine rekursive Funktion zu verwenden, und Sie sollten auf jeden Fall mit den anderen obigen Vorschlägen fortfahren.

0

Vielen Dank! Für andere Menschen ein gleiches Problem:

ich mit dem folgenden Code am Ende:

list_a = ['a','b','c','d'] 
list_b = [-6.3, 3.1, 0.5, 4.1] 
tmp = zip(a, b) 
list_a_2 = [x[0] for x in tmp if x[1] > 0.7] 
list_b_2 = [x[1] for x in tmp if x[1] > 0.7] 
del tmp 

Und eine bessere Idee könnte direkt einen Datenrahmen verwenden sein, jedes Element mit seinem eigenen Label übereinstimmen.

Verwandte Themen