Seite 1 von 1

Ohne zusätzliche eckige Klammern keine Tupel bei `Counter()`

Verfasst: Freitag 17. April 2020, 00:55
von Atalanttore
Hallo

Der Container Datentyp `Counter` verhält sich beim Hinzufügen von Tupeln mit der Methode `update()` anders als Listen mit der Methode `append()`. Im folgenden Code bedarf es bei `counter2` zusätzliche eckige Klammern um die Tupel, damit die Ausgabe identisch zur Liste `data` ist.

Weshalb benötigt es beim `Counter` zusätzliche eckige Klammern, damit die Tupel auch so erhalten bleiben?

Code: Alles auswählen

from collections import Counter
from random import randint

counter1 = Counter()
counter2= Counter()
data = []


for i in range(100):
    first = (randint(0, 1000))
    second = (randint(0, 1000))
    counter1.update((first, second))  # Tupel bleiben nicht erhalten
    counter2.update([(first, second)])  # Tupel bleiben erhalten
    data.append((first, second))

print("counter1:", sorted(counter1))
print("counter2:", sorted(counter2))
print("data:", sorted(data))
Gruß
Atalanttore

Re: Ohne zusätzliche eckige Klammern keine Tupel bei `Counter()`

Verfasst: Freitag 17. April 2020, 06:26
von Sirius3
update erwartet mehrere Elemente, das Äquivalent bei Listen wäre extend.
Daher erst die Liste erzeugen und dann den Counter:

Code: Alles auswählen

from collections import Counter
from random import randint

data = []
for i in range(100):
    first = randint(0, 1000)
    second = randint(0, 1000)
    data.append((first, second))
    
counter = Counter(data)
print("counter:", sorted(counter))
print("data:", sorted(data))


Re: Ohne zusätzliche eckige Klammern keine Tupel bei `Counter()`

Verfasst: Freitag 17. April 2020, 12:47
von Atalanttore
@Sirius3: Danke für die Erklärung.

Erst die Daten erzeugen und dann den `Counter` wird im konkreten Anwendungsfall nicht funktionieren. Es fallen laufend neue Werte an und die Werte mit den meisten Vorkommen sollen zuerst bearbeitet werden.

Re: Ohne zusätzliche eckige Klammern keine Tupel bei `Counter()`

Verfasst: Freitag 17. April 2020, 15:22
von __blackjack__
@Atalanttore: Dann benutze halt nicht die `update()`-Methode sondern addiere manuell 1. Wobei Du dann eigentlich auch den `Counter` nicht wirklich brauchst, sofern Du davon nicht noch was anderes brauchst was ein `collections.defaultdict` nicht auch bietet.

Re: Ohne zusätzliche eckige Klammern keine Tupel bei `Counter()`

Verfasst: Samstag 18. April 2020, 11:01
von __blackjack__

Code: Alles auswählen

#!/usr/bin/env python3
from collections import defaultdict
from random import randint


def main():
    histogram = defaultdict(int)
    pairs = []

    for _ in range(100):
        pair = (randint(0, 1000), randint(0, 1000))
        histogram[pair] += 1
        pairs.append(pair)

    print("histogram:", sorted(histogram))
    print("pairs:", sorted(pairs))


if __name__ == "__main__":
    main()

Re: Ohne zusätzliche eckige Klammern keine Tupel bei `Counter()`

Verfasst: Samstag 18. April 2020, 16:22
von Atalanttore
@__blackjack__: Aus dem `Counter` benutze ich noch die Methode `most_common()` zum Bestimmen der aktuell häufigsten Elemente.

Re: Ohne zusätzliche eckige Klammern keine Tupel bei `Counter()`

Verfasst: Samstag 18. April 2020, 16:37
von __blackjack__
@Atalanttore: Ah, okay. Die Lösung bleibt dann aber fast die gleiche, nur eben mit dem `Counter`-Objekt.

Re: Ohne zusätzliche eckige Klammern keine Tupel bei `Counter()`

Verfasst: Samstag 18. April 2020, 16:45
von Atalanttore
@__blackjack__: Danke.