Listenbearbeitung

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
pleasehelp!
User
Beiträge: 28
Registriert: Donnerstag 15. November 2018, 20:44

Hallo,
ich möchte ein Programm zur Textentschlüsselung schreiben und habe jetzt das Problem, dass ich nicht weiß wie ich einen Listeneintrag einer Unterliste mit dem Nächsten der gleichen Liste vergleichen kann. Danach muss ich allerdings die Buchstaben der Häufigkeit nach sortieren...
Der Code beinhaltet das ganze Programm, das Problem ist dann ab dem Kommentar nach Häufigkeit sortieren.

Code: Alles auswählen

##Informationen für den weiteren Verlauf
alphabet = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K" ,"L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "ß", "Ä", "Ö", "Ü"]
anzahl = [["A", 0],[ "B", 0],[ "C", 0],[ "D", 0], ["E", 0], ["F", 0],[ "G", 0],[ "H", 0], ["I", 0],[ "J", 0], ["K", 0] ,["L", 0],[ "M", 0], ["N", 0], ["O", 0],[ "P", 0],[ "Q", 0],[ "R", 0],[ "S", 0],[ "T", 0],[ "U", 0], ["V", 0],[ "W", 0], ["X", 0], ["Y", 0], ["Z", 0], ["ß", 0],["Ä", 0], ["Ö", 0], ["Ü", 0]]
sortiert =  []
ersetzungh = ["E", "N", "I", "R", "S", "T", "A", "H", "D", "U", "L", "C", "G", "M", "O", "B", "W", "F", "K","Z", "V", "P", "Ü", "Ä", "ß", "Ö", "J", "Y", "X", "Q"]
ersetzungw = {"A" : "A", "B" : "B", "C" : "C", "D" : "D", "E" : "E", "F": "F", "G" : "G", "H" : "H", "I" : "I", "J" : "J", "K" : "K", "L" : "L", "M" : "M", "N" : "N", "O" : "O", "P" : "P", "Q" : "Q", "R" : "R", "S" : "S", "T" : "T", "U" : "U", "V" : "V", "W" : "W", "X" : "X", "Y" : "Y", "Z" : "Z",  "ß" : "ß", "Ä" : "Ä", "Ö" : "Ö", "Ü" : "Ü"}


##Informationseingabe des Benutzers
print("Herzlich Willkommen bei ihrem Entschlüsselungsprogramm.", "\n", "Bitte geben sie bei der folgenden Texteingabe ihren zu entschlüsselten Text ein.")
text = input("Texteingabe: ")
text = text.upper()
text = text.replace(" ","")
text = text.replace(".","")
text = text.replace(":","")
text = text.replace(",","")
text = text.replace("!","")
text = text.replace(";","")
print(text)

##Häufigkeitsanalyse
b = 0
for testb in alphabet:
    a = 0
    for buchstabe in text:
        if buchstabe == alphabet[b]:
            anzahl[b][1] = anzahl[b][1] + 1
        a += 1 
    b += 1
print(anzahl)

##nach Häufigkeit sortieren
länget = len(text)
print("\n", länget, "Buchstaben insgesamt")

i = 0
j = 1
for zahl in anzahl:
    if anzahl[i][1] < anzahl[j][1]:
        zahl.append(sortiert)
    i += 1
    j += 1

print(sortiert)
Vielen Dank schonmal im Voraus!
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Als Erstes: der Code ist gruselig. Statt für deinen Zähler anzahl ein Dictionary zu verwenden baust du das aufwändig per Hand mit einer Liste nach.

Wie kann man nun eine Liste sortieren? Listen haben eine sort-Methode. Bei der Standardsortierung werden allerdings zunächst aus den inneren Listen der erste Wert (der Buchstabe; Listenindex 0) verglichen und dann erst der zweite (die Häufigkeit; Listenindex 1). Du möchtest allerdings nach dem zweiten Wert sortieren. Dafür kann man der Methode sort über den Parameter key eine Funktion mitgeben, die das Kriterium für die Sortierung liefert. In deinem Fall ist es das zweite Element der inneren Liste. Dafür gibt es in Python die Funktion itemgetter. Da das zweite Element den Index 1 hat (Listen sind null-basiert) hast du mit itemgetter(1) die Funktion schon fertig.

Beispielcode:

Code: Alles auswählen

from operator import itemgetter

data = [['H', 7], ['N', 42], ['O', 23], ['P', 1], ['T', 4], ['Y', 2]]
data.sort(key=itemgetter(1))
print(data)
Wenn die Sortierrichtung absteigend sein soll, dann kannst du der sort-Methode auch noch den Parameter `reverse` mitgeben.

Code: Alles auswählen

data.sort(key=itemgetter(1), reverse=True)
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Da du ja lernen möchtest zeige ich ein Beispiel, wie man den Code auch schreiben könnte. Ich habe mich dabei etwa an deiner Struktur orientiert, sonst sähe das noch einmal anders aus.

Code: Alles auswählen

from operator import itemgetter
import string

alphabet = string.ascii_lowercase + 'ßäöü'
anzahl = {character: 0 for character in alphabet}

text = input("Texteingabe: ")
for character in text.lower():
    if character in anzahl:
        anzahl[character] += 1

data = list(sorted(anzahl.items(), key=itemgetter(1), reverse=True))
print(data)
Ich weiß, du musst den von dir gelieferten Code auch erklären können und damit kannst du meinen Code nicht einfach übernehmen (und das ist auch gut so). Aber schau dir das einfach mal an und versuche es zu verstehen. Es sieht doch schon mal deutlich handlicher aus als deine Variante, oder?
pleasehelp!
User
Beiträge: 28
Registriert: Donnerstag 15. November 2018, 20:44

/me hat geschrieben: Samstag 24. November 2018, 11:08 Als Erstes: der Code ist gruselig. Statt für deinen Zähler anzahl ein Dictionary zu verwenden baust du das aufwändig per Hand mit einer Liste nach.

Wie kann man nun eine Liste sortieren? Listen haben eine sort-Methode. Bei der Standardsortierung werden allerdings zunächst aus den inneren Listen der erste Wert (der Buchstabe; Listenindex 0) verglichen und dann erst der zweite (die Häufigkeit; Listenindex 1). Du möchtest allerdings nach dem zweiten Wert sortieren. Dafür kann man der Methode sort über den Parameter key eine Funktion mitgeben, die das Kriterium für die Sortierung liefert. In deinem Fall ist es das zweite Element der inneren Liste. Dafür gibt es in Python die Funktion itemgetter. Da das zweite Element den Index 1 hat (Listen sind null-basiert) hast du mit itemgetter(1) die Funktion schon fertig.

Beispielcode:

Code: Alles auswählen

from operator import itemgetter

data = [['H', 7], ['N', 42], ['O', 23], ['P', 1], ['T', 4], ['Y', 2]]
data.sort(key=itemgetter(1))
print(data)
Wenn die Sortierrichtung absteigend sein soll, dann kannst du der sort-Methode auch noch den Parameter `reverse` mitgeben.

Code: Alles auswählen

data.sort(key=itemgetter(1), reverse=True)
Danke dafür schonmal, das verstehe ich sehr gut.
pleasehelp!
User
Beiträge: 28
Registriert: Donnerstag 15. November 2018, 20:44

/me hat geschrieben: Samstag 24. November 2018, 11:28 Da du ja lernen möchtest zeige ich ein Beispiel, wie man den Code auch schreiben könnte. Ich habe mich dabei etwa an deiner Struktur orientiert, sonst sähe das noch einmal anders aus.

Code: Alles auswählen

from operator import itemgetter
import string

alphabet = string.ascii_lowercase + 'ßäöü'
anzahl = {character: 0 for character in alphabet}

text = input("Texteingabe: ")
for character in text.lower():
    if character in anzahl:
        anzahl[character] += 1

data = list(sorted(anzahl.items(), key=itemgetter(1), reverse=True))
print(data)
Ich weiß, du musst den von dir gelieferten Code auch erklären können und damit kannst du meinen Code nicht einfach übernehmen (und das ist auch gut so). Aber schau dir das einfach mal an und versuche es zu verstehen. Es sieht doch schon mal deutlich handlicher aus als deine Variante, oder?
Verstehe ich fast, was bedeutet denn diese Zeilen:

Code: Alles auswählen

 alphabet = string.ascii_lowercase + 'ßäöü'
anzahl = {character: 0 for character in alphabet}
Freundliche Grüße
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@pleasehelp!: das ist eine etwas umständliche Schreibweise für

Code: Alles auswählen

anzahl = dict.fromkeys(string.ascii_lowercase + 'ßäöü', default=0)
und erzeugt einfach ein Wörterbuch mit vorbelegten Schlüsseln.
pleasehelp!
User
Beiträge: 28
Registriert: Donnerstag 15. November 2018, 20:44

@sirius3
ok, aber was heißt dann default? Achso und ascii kenne ich nur als eine ewige Tabelle von Zeichen wie man sie übersetzen kann, wie zum Beispiel in Hexadezmalzahlen, was bewirkt das hier?
Danke!
__deets__
User
Beiträge: 14539
Registriert: Mittwoch 14. Oktober 2015, 14:29

Hats du mal in die Dokumentation geschaut? Oder mal damit herumgespielt im Interpreter? So findest du das selbst raus, und wir müssen nicht die schon existierende Dokumentation hier nachplappern.
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@pleasehelp!: Schau doch einfach mal wie das Ergebnis aussieht. Und was sich ändert wenn Du den `default`-Wert änderst.

Und was bewirkt was genau? Wo genau kommst Du in der Dokumentation nicht weiter? Ist ja alles dokumentiert was da steht. Und Du kannst die Teilausdrücke auch einfach mal in einer interaktiven Python-Shell ausprobieren und schauen was für Werte Du bekommst.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
pleasehelp!
User
Beiträge: 28
Registriert: Donnerstag 15. November 2018, 20:44

__deets__ hat geschrieben: Donnerstag 29. November 2018, 15:47 Hats du mal in die Dokumentation geschaut? Oder mal damit herumgespielt im Interpreter? So findest du das selbst raus, und wir müssen nicht die schon existierende Dokumentation hier nachplappern.
Gerne, wenn ich dann nicht alles erfragen muss, was ist denn der Interpreter? Ich kenne nur meine Datei, Shell und den Workspace :roll:
Sorry programmiere noch nicht so lange...
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Der Interpreter ist das Programm das den Python-Code interpretiert, also Python. Und wenn man das einfach so startet, landet man in einer interaktiven Python-Shell. Und da kann man dann Sachen ausprobieren. Schau Dir vielleicht mal das Tutorial in der Python-Dokumentation an. Die machen da viel interaktiv.

Wenn man es etwas praktischer haben möchte, kann man sich auch IPython, bpython, oder Jupyter anschauen. Da hat man dann eine interaktive Python-Umgebung mit etwas mehr Funktionalität.

Code: Alles auswählen

>>> import string
>>> string.ascii_lowercase
'abcdefghijklmnopqrstuvwxyz'
>>> type(string.ascii_lowercase)
<class 'str'>
>>> string.ascii_lowercase + 'ßäöü'
'abcdefghijklmnopqrstuvwxyzßäöü'
>>> dict.fromkeys(string.ascii_lowercase + 'ßäöü', 0)
{'w': 0, 'm': 0, 'c': 0, 'v': 0, 'ß': 0, 'h': 0, 'l': 0, 'q': 0, 'u': 0, 't': 0, 'b': 0, 'ö': 0, 'f': 0, 'r': 0, 'i': 0, 'ä': 0, 'g': 0, 'e': 0, 'p': 0, 'z': 0, 'x': 0, 'a': 0, 'n': 0, 'd': 0, 'y': 0, 'ü': 0, 'k': 0, 'o': 0, 'j': 0, 's': 0}
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
pleasehelp!
User
Beiträge: 28
Registriert: Donnerstag 15. November 2018, 20:44

@__blackjack__

Vielen Dank hilft mir sehr weiter!
pleasehelp!
User
Beiträge: 28
Registriert: Donnerstag 15. November 2018, 20:44

Hallo, habe das Ganze jetzt mal etwas abgekürzt und ich muss am Ende allerdings den eingegebenen Text dechiffriert ausgeben. Jetzt hakt es bei dem Ersetzten der Buchstaben. Habe etwas ausprobiert, aber ich bekomme immer den unveränderten Text ausgegeben. Vielleicht hat jemand nochmal einen Tipp für mich.

Code: Alles auswählen

from operator import itemgetter

##Informationen für den weiteren Verlauf
anzahl = dict.fromkeys(string.ascii_uppercase + 'ßÄÖÜ', 0)
ersetzungh = ["E", "N", "I", "R", "S", "T", "A", "H", "D", "U", "L", "C", "G", "M", "O", "B", "W", "F", "K","Z", "V", "P", "Ü", "Ä", "ß", "Ö", "J", "Y", "X", "Q"]

##Informationseingabe des Benutzers
print("Herzlich Willkommen bei ihrem Entschlüsselungsprogramm.", "\n", "Bitte geben sie bei der folgenden Texteingabe ihren zu entschlüsselten Text ein.")
text = input("Texteingabe: ")
for character in text.upper():
    if character in anzahl:
        anzahl[character] += 1
daten = list(sorted(anzahl.items(), key=itemgetter(1), reverse=True))
print(daten)

##Ersetzung
a = 0
for richtig in ersetzungh:
    for buchstabe in text:
        if buchstabe == daten[a][0]:
            buchstabe = richtig
    a += 1
print(text)
__deets__
User
Beiträge: 14539
Registriert: Mittwoch 14. Oktober 2015, 14:29

Strings sid in Python immer unveränderlich. Du kannst also keine Buchstaben darin austauschen.

Du musst stattdessen einen NEUEN String bauen, der entweder den alten oder den neuen Buchstaben enthält.

Code: Alles auswählen

ergebnis = []
for richtig in ersetzungh:
    for a, buchstabe in enumerate(text):
        if buchstabe == daten[a][0]:
            buchstabe = richtig
        ergebnis.append(buchstabe)
ergebnis = “”.join(ergebnis)
pleasehelp!
User
Beiträge: 28
Registriert: Donnerstag 15. November 2018, 20:44

Hey, ok das wusste ich nicht, alleridngs versuche ich das jetzt zu programmieren und ich habe es für mich etwas übersichtlicher gemacht und bekomme aber eine Fehlermeldung...

Code: Alles auswählen

neu = []
x = 0
while x < len(daten)-1:
    neu.append(daten[x][0])
    x += 1
print(neu)

ergebnis = []
for richtig in ersetzungh:
    a = 0
    for buchstabe in enumerate(text):
        if buchstabe == neu[a]:
            buchstabe = richtig
        ergebnis.append(buchstabe)
    a += 1
ergebnis = "".join(ergebnis)

Code: Alles auswählen

Traceback (most recent call last):
  File "E:\Informatik\Programme\python\meineSkripte\Hackerprogramm.py", line 34, in <module>
    ergebnis = "".join(ergebnis)
TypeError: sequence item 0: expected str instance, tuple found
verstehe nicht warum in der Liste kein string sein sollte...
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@pleasehelp!: Was soll denn diese komische ``while``-Schleife mit dem `neu` da? Das sieht alles sehr umständlich aus. Erst mal wäre das eine ``for``-Schleife weil man ja einfach über die entsprechenden `x`-Werte iterieren kann, statt das `x` so umständlich vorher zu initialisieren und in jedem Schleifendurchlauf hoch zu zählen. Und dann ist das aber immer noch zu umständlich mit hochgezählten `x`-Werten als Index auf `daten` zuzugreifen, weil man auch gleich direkt eine ``for``-Schleife über `daten`, ohne den Umweg über das `x` schreiben kann. Und da auf eine ziemlich simple Art eine neue Liste erstellt wird, kann man das dann auch noch als „list comprehension“ ausdrücken.

In der Liste sind keine Zeichenketten weil `buchstabe` keine Zeichenkette ist, sondern ein Tupel. Schau Dir mal an was die `enumerate()`-Funktion macht. Und/oder lass Dir doch einfach mal `ergebnis` ausgeben bevor Du versuchst das bei `join()` als Argument zu übergeben.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
pleasehelp!
User
Beiträge: 28
Registriert: Donnerstag 15. November 2018, 20:44

@__blackjack__ : Die "while" Schleife ist das Einzige was ich zu 100% kann, weil wir das kurz in der Schule gemacht haben und ich versuche das noch schöner zu machen, möchte erstmal das Grundgerüst stehen haben.
Ich habe die enumerate() nachgeschaut, aber wenn ich sie weglasse kommt die Anzeige nicht mehr, dann bekomme ich nur eine ewig lange Zeichenkette ausgegeben.
Freundliche Grüße
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@pleasehelp!: IMHO hat das mit der ``while``-Schleife nichts mit Schönheit zu tun. Das ist keine Geschmacksfrage da *nicht* ``while`` zu verwenden, sondern das ist schlicht das falsche Werkzeug für diese Teilaufgabe. Wenn das mit der ``while``-Schleife Deinem aktuellen können entspricht, dann ist der ganze Rest viel zu hoch für Dich und Du musst halt lernen bis Du auf einem Kenntnisstand bist das zu verstehen. Die ``while``-Schleife durch eine ``for``-Schleife zu ersetzen, und da dann das `x` durch direktes iterieren über die Elemente von `daten`, und daraus dann eine „list comprehension“ zu machen, ist etwas was man nach dem Grundlagentutorial in der Python-Dokumentation eigentlich können sollte. Arbeite das mal durch. Das Wissen von dort *braucht* man.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
pleasehelp!
User
Beiträge: 28
Registriert: Donnerstag 15. November 2018, 20:44

@__blackjack__ Ok, ich habe versucht alles zu erfassen, kann es auch umformen, wenn das nötig ist. Ich habe nur leider nicht soviel Zeit mich tief in die Materie einzuarbeiten und versuche das Nötigste zu lernen und zu verstehen, da ich in einer Woche abgeben muss und noch nicht wirklich am Ziel bin...
Danke dann und bis dann...
Antworten