Hallo zusammen,
ich habe folgendes Problem:
Ich muss aus einer Textdatei zählen, wie oft jeder Buchstabe (a-z) vorkommt und welcher der häufigste ist.
Mein Ansatz ist mit viel Schreibarbeit verbunden, das klappt zwar aber ich würde es lieber mit einer For schleife lösen, da komme ich allerdings nicht weiter.
Hat jemand vielleicht einen Tipp/Ansatz ?
Vielen Dank
Buchstaben aus einer Textdatei zählen
- __blackjack__
- User
- Beiträge: 14019
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Marieee: Der Ansatz wäre eine ``for``-Schleife über die eingelesenen Daten zu schreiben. 
Wo kommst Du denn konkret nicht weiter? Sollen Grossbuchstaben wie Kleinbuchstaben zählen? Also ist in "Hoho" zweimal "h" oder einmal "H" und einmal "h"? Sollen wirklich nur A bis Z gezählt werden, oder auch andere Buchstaben wie Ä und ß? Was wäre mit π oder Δ?
Am einfachsten wäre es übrigens `collections.Counter` zu verwenden.
Wo kommst Du denn konkret nicht weiter? Sollen Grossbuchstaben wie Kleinbuchstaben zählen? Also ist in "Hoho" zweimal "h" oder einmal "H" und einmal "h"? Sollen wirklich nur A bis Z gezählt werden, oder auch andere Buchstaben wie Ä und ß? Was wäre mit π oder Δ?
Am einfachsten wäre es übrigens `collections.Counter` zu verwenden.
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
Ich hab es jetzt mittels collection.counter versucht. Dies klappt auch soweit für eingegebene Texte. Wenn ich jetzt versuche mich auf eine Textdatei zu beziehen bekomme ich es nicht hin.
Es soll nur A-Z gezählt werden und groß und klein - Schreibung soll nicht unterschieden werden.
f = open("Text.txt", "r")
data = f.read()
count = Counter()
count.update('data')
print('\n')
for char in 'abcdefghijklmnopqrstuvwxyz':
print('%s : %d' % (char, count[char]))
Es soll nur A-Z gezählt werden und groß und klein - Schreibung soll nicht unterschieden werden.
f = open("Text.txt", "r")
data = f.read()
count = Counter()
count.update('data')
print('\n')
for char in 'abcdefghijklmnopqrstuvwxyz':
print('%s : %d' % (char, count[char]))
- __blackjack__
- User
- Beiträge: 14019
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Marieee: Was ist denn der Unterschied zwischen ``print(data)`` und ``print("data")``? Genau den Fehler machst Du da.
Edit: Zeichenkettenformatierung mit ``%`` macht man nicht mehr, dafür gibt es f-Zeichenketten. Und die ASCII-Kleinbuchstaben gibt es im `string`-Modul, die muss man nicht selbst eintippen.
Edit2: Ach so: Du unterscheidest zwischen Gross- und Kleinschreibung, das heisst Grossbuchstaben werden bei Deinem Code einfach gar nicht gezählt.
Edit: Zeichenkettenformatierung mit ``%`` macht man nicht mehr, dafür gibt es f-Zeichenketten. Und die ASCII-Kleinbuchstaben gibt es im `string`-Modul, die muss man nicht selbst eintippen.
Edit2: Ach so: Du unterscheidest zwischen Gross- und Kleinschreibung, das heisst Grossbuchstaben werden bei Deinem Code einfach gar nicht gezählt.
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
Man sollte auch nicht über alle Buchstaben des Alphabets, sondern über den Counter iterieren. Ansonsten wirft das einen Fehler, falls einer der Buchstaben nicht im Text enthalten ist. Oder man macht es via ``count.get(char, 0)``.
- __blackjack__
- User
- Beiträge: 14019
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@snafu: Nee das ist schon okay so. `collections.Counter` liefert 0 bei Zugriff auf unbekannte Schlüssel:
Code: Alles auswählen
In [1034]: counter = collections.Counter()
In [1035]: counter[42]
Out[1035]: 0
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
'collections.Counter' ist hier korrekt, wie die anderen schon meinten. Lernenden, die allerdings nicht wüssten, wie es sonst geht, kann ich nur empfehlen, zur Übung z.B. auch die "klassische" Variante mit einem Dictionary zu probieren. Die Dinge, die man dafür benötigt, sollte man finde ich in jedem Fall beherrschen und das wäre dann eine Gelegenheit, an dieser Lücke zu arbeiten.
- __blackjack__
- User
- Beiträge: 14019
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Klassisch kenne ich das eher in diese Richtung (also das zählen, nicht die Aufbereitung für die Ausgabe):
Ausgabe für den englischen Text von „Alice in Wonderland“:
Code: Alles auswählen
#!/usr/bin/env python3
import sys
from string import ascii_lowercase
import rich
from rich.bar import Bar
from rich.box import ROUNDED
from rich.table import Column, Table
def main():
counters = [0] * len(ascii_lowercase)
for line in sys.stdin:
for character in line.lower():
if "a" <= character <= "z":
counters[ord(character) - ord("a")] += 1
result = sorted(
zip(ascii_lowercase, counters), key=lambda item: (-item[1], item[0])
)
total_count = sum(count for character, count in result)
table = Table(
Column("character", justify="center"),
Column("count", f"{total_count:,}", justify="right"),
"",
title="Character frequencies",
box=ROUNDED,
show_footer=True,
highlight=True,
)
max_count = result[0][1]
for character, count in result:
table.add_row(
repr(character),
f"{count:,}",
Bar(max_count, 0, count, color="bright_blue"),
)
rich.print(table)
if __name__ == "__main__":
main()
Code: Alles auswählen
$ ./forum12.py < nltk_data/corpora/gutenberg/carroll-alice.txt
Character frequencies
╭───────────┬─────────┬────────────────────────────────────────────────────────╮
│ character │ count │ │
├───────────┼─────────┼────────────────────────────────────────────────────────┤
│ 'e' │ 13,570 │ ██████████████████████████████████████████████████████ │
│ 't' │ 10,685 │ ██████████████████████████████████████████▌ │
│ 'a' │ 8,791 │ ██████████████████████████████████▉ │
│ 'o' │ 8,145 │ ████████████████████████████████▍ │
│ 'i' │ 7,510 │ █████████████████████████████▉ │
│ 'h' │ 7,372 │ █████████████████████████████▎ │
│ 'n' │ 7,012 │ ███████████████████████████▉ │
│ 's' │ 6,500 │ █████████████████████████▊ │
│ 'r' │ 5,437 │ █████████████████████▋ │
│ 'd' │ 4,929 │ ███████████████████▌ │
│ 'l' │ 4,713 │ ██████████████████▊ │
│ 'u' │ 3,465 │ █████████████▊ │
│ 'w' │ 2,675 │ ██████████▋ │
│ 'g' │ 2,531 │ ██████████ │
│ 'c' │ 2,398 │ █████████▌ │
│ 'y' │ 2,263 │ █████████ │
│ 'm' │ 2,104 │ ████████▎ │
│ 'f' │ 2,000 │ ███████▉ │
│ 'p' │ 1,524 │ ██████ │
│ 'b' │ 1,476 │ █████▊ │
│ 'k' │ 1,158 │ ████▌ │
│ 'v' │ 846 │ ███▎ │
│ 'q' │ 209 │ ▊ │
│ 'x' │ 148 │ ▌ │
│ 'j' │ 146 │ ▌ │
│ 'z' │ 78 │ ▎ │
├───────────┼─────────┼────────────────────────────────────────────────────────┤
│ │ 107,685 │ │
╰───────────┴─────────┴────────────────────────────────────────────────────────╯
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
@__blackjack__: Also wenn es um das klassisch geht – Mit dem ganzen syntaktischen Zucker & Komfort von Python und insbesondere ohne selbstgeschriebene Sortierfunktion ist das für mich allenfalls neoklassisch
(aber natürlich schick umgesetzt).

- __blackjack__
- User
- Beiträge: 14019
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Wenn man sich nur die erste Zeile von dem Alice im Wunderland-Text auswerten lässt, kommt eine interessante Gesamtbuchstabenanzahl bei heraus
:
@nezzcarth: Hier in klassich, statt neoklassich:
Lauffähig auf einem VIC-20 in Grundausstattung (allerdings mit Diskettenlaufwerk):
1 Stunde 38 Minuten und 20 Sekunden Laufzeit. Oder heisst das dann eher Kriechzeit‽ 
Code: Alles auswählen
$ head -n 1 nltk_data/corpora/gutenberg/carroll-alice.txt | ./forum12.py
Character frequencies
╭───────────┬───────┬──────────────────────────────────────────────────────────╮
│ character │ count │ │
├───────────┼───────┼──────────────────────────────────────────────────────────┤
│ 'e' │ 5 │ ████████████████████████████████████████████████████████ │
│ 'l' │ 5 │ ████████████████████████████████████████████████████████ │
│ 'a' │ 4 │ ████████████████████████████████████████████▊ │
│ 'n' │ 4 │ ████████████████████████████████████████████▊ │
│ 'r' │ 4 │ ████████████████████████████████████████████▊ │
│ 'd' │ 3 │ █████████████████████████████████▌ │
│ 'i' │ 3 │ █████████████████████████████████▌ │
│ 's' │ 3 │ █████████████████████████████████▌ │
│ 'c' │ 2 │ ██████████████████████▍ │
│ 'o' │ 2 │ ██████████████████████▍ │
│ 'w' │ 2 │ ██████████████████████▍ │
│ 'b' │ 1 │ ███████████▏ │
│ 't' │ 1 │ ███████████▏ │
│ 'u' │ 1 │ ███████████▏ │
│ 'v' │ 1 │ ███████████▏ │
│ 'y' │ 1 │ ███████████▏ │
│ 'f' │ 0 │ │
│ 'g' │ 0 │ │
│ 'h' │ 0 │ │
│ 'j' │ 0 │ │
│ 'k' │ 0 │ │
│ 'm' │ 0 │ │
│ 'p' │ 0 │ │
│ 'q' │ 0 │ │
│ 'x' │ 0 │ │
│ 'z' │ 0 │ │
├───────────┼───────┼──────────────────────────────────────────────────────────┤
│ │ 42 │ │
╰───────────┴───────┴──────────────────────────────────────────────────────────╯
Code: Alles auswählen
10 ti$="000000":dim c(25),ci(25):a=asc("a"):ua=asc("A")
20 z=asc("z"):uz=asc("Z"):n=0
100 open 2,8,2,"alice,s"
110 get#2,c$:if st<>0 then 160
120 c=asc(c$):if c=13 then n=n+1:print n:print "{up}";:goto 110
130 if ua<=c and c<=uz then c=c-128
140 if a<=c and c<=z then j=c-a:c(j)=c(j)+1
150 goto 110
160 close 2
200 for i=0 to 25:ci(i)=i:next
210 f=0:for i=0 to 24:if c(i)>=c(i+1) then 230
220 f=-1:t=c(i):c(i)=c(i+1):c(i+1)=t:t=ci(i):ci(i)=ci(i+1):ci(i+1)=t
230 next:if f then 210
300 tc=0:for i=0 to 12
310 print chr$(ci(i)+a);c(i);tab(10);chr$(ci(i+13)+a);c(i+13)
320 tc=tc+c(i)+c(i+13):next:print "total characters:":print tc
1000 print "in";ti/60;"s"
Code: Alles auswählen
RUN
E 13570 G 2531
T 10685 C 2398
A 8791 Y 2263
O 8145 M 2104
I 7510 F 2000
H 7372 P 1524
N 7012 B 1476
S 6500 K 1158
R 5437 V 846
D 4929 Q 209
L 4713 X 148
U 3465 J 146
W 2675 Z 78
TOTAL CHARACTERS:
107685
IN 5900.68333 S
READY.
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
- DeaD_EyE
- User
- Beiträge: 1231
- Registriert: Sonntag 19. September 2010, 13:45
- Wohnort: Hagen
- Kontaktdaten:
Es gibt viele Ansätze. Ich hoffe, das sind keine Hausaufgaben....
Python-Basic:
Python-Basic:
Code: Alles auswählen
import string
def count1(text):
text = text.lower()
result = {}
for char in text:
if char not in string.ascii_lowercase:
continue
if char not in result:
result[char] = 1
else:
result[char] += 1
return result
def count2(text):
text = text.lower()
result = {}
for char in text:
if char not in string.ascii_lowercase:
continue
# wenn der key char nicht existiert,
# liefert die methode get das zweite Argument zurück.
# in diesem falll eine 0
result[char] = result.get(char, 0) + 1
return result
# mit defaultdict weniger code
from collections import defaultdict
def count3(text):
text = text.lower()
result = defaultdict(int)
for char in text:
if char not in string.ascii_lowercase:
continue
result[char] += 1
return result
# mit Counter noch weniger code
from collections import Counter
def count4(text):
return Counter(char for char in text.lower() if char in string.ascii_lowercase)
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Wobei man das continue vermeiden würde und direkt den Code in den if-Block packen würde:
Code: Alles auswählen
def count3(text):
text = text.lower()
result = defaultdict(int)
for char in text:
if char in string.ascii_lowercase:
result[char] += 1
return result
- __blackjack__
- User
- Beiträge: 14019
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Oder man packt vorher mal 0en für alle Zeichen in das Wörterbuch:
Falls man `fromkeys()` nicht kennt, gibt's ja noch andere Möglichkeiten. Notfalls mit einer Schleife.
Code: Alles auswählen
import string
def count0(text):
result = dict.fromkeys(string.ascii_lowercase, 0)
for character in text.lower():
if character in result:
result[character] += 1
return result
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
@__blackjack__: Die BASIC Variante entspricht in der Zeilenanzahl ca. meinem Versuch mit gawk. Ich finde es jedoch beeindruckend, wie "dicht" BASIC anscheinend ist. 

Code: Alles auswählen
#!/usr/bin/gawk -f
BEGIN {
FS=""
PROCINFO["sorted_in"] = "@val_num_asc"
}
{
for (i=1; i<=NF; i++) {
if ($i ~ /[a-zA-Z]/) {
total += 1
counts[tolower($i)] += 1
}
}
}
END {
for (key in counts)
printf "%s %d %3.2f%%\n", key, counts[key], counts[key]/total*100
print "Total:", total
}
Code: Alles auswählen
./count.awk carroll-alice.txt
z 78 0.07%
j 146 0.14%
x 148 0.14%
q 209 0.19%
v 846 0.79%
k 1158 1.08%
b 1476 1.37%
p 1524 1.42%
f 2000 1.86%
m 2104 1.95%
y 2263 2.10%
c 2398 2.23%
g 2531 2.35%
w 2675 2.48%
u 3465 3.22%
l 4713 4.38%
d 4929 4.58%
r 5437 5.05%
s 6500 6.04%
n 7012 6.51%
h 7372 6.85%
i 7510 6.97%
o 8145 7.56%
a 8791 8.16%
t 10685 9.92%
e 13570 12.60%
Total: 107685
- __blackjack__
- User
- Beiträge: 14019
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@nezzcarth: Ich fand das ja geradezu luftig locker wenn man bedenkt wie viele optionale Leerzeichen da drin sind, und das ich mich nicht besonders bemüht habe möglichst viel in jede Zeile zu packen.
Die Leerzeichen sind da hauptsächlich für den Syntax-Highlighter hier, die hätte ich zumindest früher nicht geschrieben. Auf dem VIC-20 sowieso nicht, weil noch früher in der Anzeige umgebrochen wird als auf dem C64. 22 Zeichen pro Zeile 40 beim C64. Das hätte also eher so ausgesehen:
Code: Alles auswählen
100 TI$="000000":DIMC(25),CI(25):N=0:OPEN2,8,2,"ALICE,S"
110 GET#2,C$:IFST<>0THENCLOSE2:FORI=0TO25:CI(I)=I:NEXT:GOTO210
120 C=ASC(C$):IFC=13THENN=N+1:PRINTN:PRINT"{UP}";:GOTO110
130 IF193<=CANDC<=218THENC=C-128
140 IF65<=CANDC<=90THENJ=C-A:C(J)=C(J)+1
150 GOTO110
210 F=0:FORI=0TO24:IFC(I)>=C(I+1)THEN230
220 F=-1:T=C(I):C(I)=C(I+1):C(I+1)=T:T=CI(I):CI(I)=CI(I+1):CI(I+1)=T
230 NEXT:IFFTHEN210
300 TC=0:FORI=0TO12:PRINTCHR$(CI(I)+A);C(I);TAB(10);CHR$(CI(I+13)+A);C(I+13)
320 TC=TC+C(I)+C(I+13):NEXT:PRINT"TOTAL CHARACTERS:":PRINTTC
999 PRINT"IN";TI/60;"S"
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis