2016-09-23 5 views
-1

Ich habe eine Liste von ganzen Zahlen (das sind nicht ganze Zahlen in der realen Welt, das ist nur für die Einfachheit der Frage), und ich möchte die positiven UND die negative filtern Einsen (beide Listen interessieren mich)trennen Sie eine Liste in 2 Listen mit einem Kriterium

Meine Lösungen:

main_list = [50,-354,10,34,-56,10] 

negatives = list(filter(lambda x : x < 0,main_list)) 
positives = list(filter(lambda x : x >= 0,main_list)) 

Werke, sondern führt 2 filter Operationen

for i in main_list: 
    if i < 0: 
     negatives.append(i) 
    else: 
     positives.append(i) 

funktioniert, aber nicht sehr pythonic.

Das Erstellen von Mengen und Subtrahieren der positiven Elemente von der Hauptliste ist keine Option, da unnötiges Hashing verwendet wird.

Gibt es einen eleganteren Weg das zu tun? (Einzeiler sehr geschätzt)

Edit: Ich habe nicht so schlecht gefunden (und unterscheiden sich von den Antworten der ursprünglichen Frage), wie es von onelining ohne zu viele Tests

for i in main_list: (negatives if i < 0 else positives).append(i) 
+0

Wie groß der Liste ist es? Kannst du es sortieren? Summieren Sie es? – MooingRawr

+2

Warum denkst du, dass das zweite Beispiel nicht sehr pythonisch ist? –

+0

@ JonClements Persönlich denke ich, es sieht sehr ähnlich wie jede andere Sprache. Aber es hat iterables und was nicht, aber die meisten Leute, die ich auch gesprochen habe, denken, dass Python hauptsächlich Magic One Liners ist. – MooingRawr

Antwort

2

Je nachdem, was Ihre ursprüngliche Kriterien ist, Sie itertools.groupby verwenden:

>>> from itertools import groupby 
>>> {str(k):list(g) for k, g in groupby(sorted(main_list), key=lambda x: x < 0)} 
{'False': [10, 10, 34, 50], 'True': [-354, -56]} 

Aber man kann nicht sagen, ob dies effizienter als zwei Listenkomprehensionen ist oder die für Schleife, wenn Sie Zeit die Leistung der beiden (die sieht ok) Ansätze.

+0

Das erfordert eine 'O (n log n)' Sortierung und ein Lambda, also würde ich überrascht sein, dass es schneller war als eine lineare Lösung. –

0

Wie wäre es mit einer Kopie des Originals als positives anzufangen und dann die negatives durch Elemente aus dem positives auf einmal zu füllen?

Nutzung von der pop ‚Rückkehr

main_list = [50, -354, 10, 34, -56, 10] 

positives = main_list[:] 
negatives = [positives.pop(positives.index(x)) for x in main_list if x < 0] 
print(positives) # -> [50, 10, 34, 10] 
print(negatives) # -> [-354, -56] 
Verwandte Themen