2017-05-21 1 views
3

Mit dem Collection Counter,Kann ich einen Counter in eine Liste von Listen ohne Multiples umkehren?

l1 = ['a', 'b', 'b', 'c', 'c', 'b', 'e'] 
l2 = ['a', 'b', 'b', 'c', 'c', 'b','d'] 

from collections import Counter 

c1 = Counter(l1) 
c2 = Counter(l2) 

# Intersection 
c1 & c2 

>>> Counter({'b': 3, 'c': 2, 'a': 1}) 

Welchem ​​Idiom könnte verteilen Sammlungen Zähler in eine Liste von Listen, in denen jeweils mehrere in jeder Liste nur einmal angezeigt wird?

[['a', 'b', 'c'],['b', 'c'],['b']] 
+0

Ist die Reihenfolge in der endgültigen Liste wichtig oder nur der Inhalt? – MSeifert

+0

Der Collections Counter gibt ein 'dict' zurück, also glaube ich, dass wir in diesem Punkt kein Glück haben. Trotzdem ist das auch ein gutes Problem - nehmen Sie zwei Listen mit Vielfachen und geben Sie eine Liste von Listen jeder Liste ohne Vielfache zurück. – xtian

Antwort

7

Sie nicht wissen, ob Sie für einen Einzeiler gesucht haben, aber hier ist ein Einzeiler:

Code:

[sorted(y for y in z if y is not None) 
     for z in it.izip_longest(*[[k] * l for k, l in c.items()])] 

Wie?

Zwei wichtige Dinge hier:

  1. [k] * l gibt eine Liste der Zählertasten, die Zählerwerte lange
  2. izip_longest() die Listen togther wird gesetzt ist und Pad für die kürzeren Listen mit keiner füllen

Testcode:

from collections import Counter 
c = Counter({'b': 3, 'c': 2, 'a': 1}) 

import itertools as it 
print([sorted(y for y in z if y is not None) 
     for z in it.izip_longest(*[[k] * l for k, l in c.items()])]) 

Ergebnisse:

[['a', 'b', 'c'], ['b', 'c'], ['b']] 
0

Sie können dies versuchen:

import itertools 

the_dict = {'b': 3, 'c': 2, 'a': 1} 

the_frequencies = [[a]*b for a, b in the_dict.items()] 

the_list = itertools.izip_longest(the_frequencies) 

the_final = map(list, list(itertools.izip_longest(*the_frequencies))) 

print [[i for i in b if i != None] for b in the_final] 

Diese Lösung verwendet itertools die Listen in the_frequencies enthaltenen zip, die durch Multiplizieren einer Liste der Schlüssel erstellt werden multipliziert seine entsprechenden Wert. izip erstellt dann eine Liste mit den Zeilen der Elemente in den _frequencies und speichert None, wenn die Zählung der aktuellen Iteration größer ist als die Länge einer Liste in der Liste der Listen.

+0

Eine Erklärung, wie und warum es funktioniert, wäre gut. – MSeifert

+0

In Python 3.5 ist 'izip_longest()' jetzt 'zip_longest()' – xtian

Verwandte Themen