Sortieren von Listen mit sort()

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.
Charly

Sortieren von Listen mit sort()

Beitragvon Charly » Mittwoch 14. September 2005, 15:31

Hallo,

ich will ein Perl-Code in Python umsetzten. Dabei komme ich an eine Stelle, an der ich nicht weiter komme.

Perl-Code

Code: Alles auswählen

sub sort_by_ref { 
  return substr($zk, $refs[$a]) cmp substr($zk, $refs[$b]);
}

# @refs ist einfach ein Feld von 0-5
@sort_refs = sort sort_by_ref @refs;


In Perl funktioniert das wunderbar. Allerdings kappt das in Python so nicht!

Code: Alles auswählen

def sort_by_ref(): 
  global zk
  global refs
  return cmp(zk[:refs[a]], zk[:refs[b]])

sort_refs = refs.sort(sort_by_ref())


Fehlermeldung: NameError: global name 'a' is not defined

Für 'b' wird das gleiche gelten!
Hat einer eine Idee wie das bei Python geht? Ich müsste auf die Listen-Werte von der Sort-Funktion zugreifen können, wenn ich den Perl-Code richtig interpretiert habe!

Edit (Leonidas): Code in Python-Tags gesetzt.
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Mittwoch 14. September 2005, 15:42

Was macht denn diese Perl-Funktion genau?

Funktionen 1:1 in Python zu schreiben wird scheitern, schon allein die Vorraussetzung global zu benutzen ist schon recht unangenehm.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Charly

Beitragvon Charly » Mittwoch 14. September 2005, 15:48

Die Funktion gehört zu einem Programm, das die längste doppelt vorkommende Zeichenkette in einem Text sucht.

Die Funktion sortiert das Referenzarray refs

Bsp.
Banana
längste doppelte Zeichenkette "ana"

zk = banana
refs = [0,1,2,3,4,5]
sort_refs soll werden [5,3,1,0,4,2] das entspricht aaabnn (Sortiert Banana)
Benutzeravatar
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Beitragvon mitsuhiko » Mittwoch 14. September 2005, 15:52

Dann poste mal die Ganze Perl Funktion, und deinen Python Code. Sonst ist das hier nur Raten.
Python findet a nicht, wie soll es auch, immerhin wurde es ja nicht initialisiert.
TUFKAB – the user formerly known as blackbird
Gast

Beitragvon Gast » Mittwoch 14. September 2005, 15:58

In Perl ist a und b auch nicht initialisiert!
a und b sind die Werte mit dem die sort Funktion in Perl arbeitet!

Auch wenn ich glaube das der Code in diesem Falle nicht weiterhilft, hier der Perl-Code

Code: Alles auswählen

use strict;
 use Data::Dumper; 
 use English;
 
 #-------------------------------------------------------------------
 #  Variablendeklaration
 #-------------------------------------------------------------------
 my $zk = "";         # Gesamte Zeichenkette
 my @refs;            # Referenz_Array
 my @sort_refs;         # Sortiertes Referenz_Array
 my $temp;            # Temp
 my $maxIndex = 0;      # Start Index zur Maximalen Länge
 my $maxLen = 0;      # Maximale Länge
 
 #-------------------------------------------------------------------
 #  Funktion zum lexikalischen Sortieren von Referenzarrays
 #  Die Funktion verlgeicht bzw. sortiert 2 Substrings
 #  return  <0 / 0 / >0
 #-------------------------------------------------------------------
 sub sort_by_ref { 
   return substr($zk, $refs[$a]) cmp substr($zk, $refs[$b]);   
 }
 
 #-------------------------------------------------------------------
 #  Gibt die Laenge der gleichen Anfangszeichenketten zurueck
 #  Vergleicht 2 Zeichenketten
 #  param: 2 strings
 #  return: Anzahl der länge der gleichen Zeichen
 #-------------------------------------------------------------------
 sub common_substring {
   my $substring1 = shift;
   my $substring2 = shift;
   my $min;
   my $count = 0;
   if(length $substring1 < length $substring2){
       $min = length $substring1;
   }
   else{
       $min = length $substring2;
   }
   # Durläuft so lange wie die länge des kürzeren Substrings
   # Zählt die anzahl der gleichen Zeichen
   for (my $i = 0; $i < $min; $i++){
          if (substr($substring1, $i, 1) ne substr($substring2, $i, 1)) {   
           last;
        }
        $count++;
   }
   return $count;
 }
 
 #-------------------------------------------------------------------
 #  Einlesen der Quelldatei und Ersetzen von Zeilenumbruechen
 #  durch Leerzeichen
 #-------------------------------------------------------------------
 undef $INPUT_RECORD_SEPARATOR;
 open(INPUT, "/home/Charly/Skriptsprachen-Dateien/Stechlin-01.txt") || die "Datei nicht gefunden\n";
     $zk = <INPUT>;   
 close(INPUT);
 
 $zk =~ s/\n/ /g;
 
 
 #-------------------------------------------------------------------
 #  Anlegen des Referenzarrays
 #  Feld[i] = i
 #-------------------------------------------------------------------
 for(my $i = 0; $i < length $zk; $i++){
     $refs[$#refs +1] = $i;   
 }
 
 #-------------------------------------------------------------------
 #  Sortieren des Referenzarrays
 #  Alphabetisch
 #-------------------------------------------------------------------
 @sort_refs = sort sort_by_ref @refs;
 
 #-------------------------------------------------------------------
 #  Suchen nach doppelt vorkommenden Zeichenketten
 #-------------------------------------------------------------------
 for(my $i = 0; $i <= $#sort_refs; $i++){
     $temp = substr $zk, $sort_refs[$i];
     
     # Wenn die von common_substring zrückgegebene länge größer ist als maxLen,
     if(common_substring($temp, (substr $zk, $sort_refs[$i+1])) > $maxLen){
         $maxLen = common_substring($temp, substr $zk, $sort_refs[$i+1]);
         $maxIndex = $sort_refs[$i];
         #print $maxIndex." ".$maxLen."\n";
     }
 }
 print $#sort_refs."\n";
 print "Laengste doppelt vorkommende Zeichenkette: \n\n";
 print substr $zk, $maxIndex, $maxLen;   # Ausgabe der längsten Zeichenkette (Zeichenkette, Start, Länge)
 print "\n$maxLen";
Charly

Beitragvon Charly » Mittwoch 14. September 2005, 16:38

Die Lösung habe ich jetzt mit Hilfe von google.de erraten:

Code: Alles auswählen

#-------------------------------------------------------------------
#  Funktion zum lexikalischen Sortieren von Referenzarrays
#-------------------------------------------------------------------
def sort_by_ref(a,b): 
  global zk
  global refs
  start = zk[b:b+1]
  ende = zk[a:a+1]
  erg = cmp(start, ende)
  return erg
           
#-------------------------------------------------------------------
#  Sortieren des Referenzarrays
#-------------------------------------------------------------------
refs_sort = refs[:]
refs_sort.sort(sort_by_ref)


Edit (Leonidas): Code in Python-Tags gesetzt.
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Mittwoch 14. September 2005, 17:28

Das finde ich besser:

Code: Alles auswählen

def sort_by_ref(a,b): 
  start = zk[b:b+1]
  ende = zk[a:a+1]
  return cmp(start, ende)

Keine globals, keine unbenötigten Variablen.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
jens
Moderator
Beiträge: 8458
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Beitragvon jens » Mittwoch 14. September 2005, 17:57

Leonidas hat geschrieben:Keine globals, keine unbenötigten Variablen.

Und was ist mit zk ??? :lol:

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Mittwoch 14. September 2005, 18:04

jens hat geschrieben:Und was ist mit zk ??? :lol:

zk ist die Liste, die wird aber nicht mit dem Schlüsselwort unnötigerweise als global definiert.

Man kann natürlich auch OOP anwenden, aber zumindest sollte man vermeiden auf globale Variablen schreibend zuzugreifen (Nebeneffekt/wirkung).
My god, it's full of CARs! | Leonidasvoice vs Modvoice
BlackJack

Beitragvon BlackJack » Mittwoch 14. September 2005, 22:11

Leonidas hat geschrieben:
jens hat geschrieben:Und was ist mit zk ??? :lol:

zk ist die Liste, die wird aber nicht mit dem Schlüsselwort unnötigerweise als global definiert.

Man kann natürlich auch OOP anwenden, aber zumindest sollte man vermeiden auf globale Variablen schreibend zuzugreifen (Nebeneffekt/wirkung).


Wobei ich hier mal wieder anmerken möchte das es in Python keine Variablen im klassischen Sinn gibt. Nebeneffekte kann man ohne ``global`` problemlos haben wenn die Objekte "mutable" sind, man kann nur den Namen eines "äusseren" Objekts nicht an ein anderes Objekt binden wenn man es nicht als ``global`` deklariert.

Und auch ich bin der Meinung der anderen: Man sollte keine Programme zwischen verschiedenen Programmiersprachen 1:1 umsetzen sondern lieber das Problem verstehen und in der Zielsprache formulieren.

Ich denke man muss auch noch nichtmal OO anwenden um auf die globalen Namen zu verzichten. Konsequent Funktionsparameter und Rückgabewerte benutzen reicht für den Anfang.

Diese nette kleine Funktion erstellt zum Beispiel ohne ``global`` eine sortierte Referenzliste für die übergebene Zeichenkette:

Code: Alles auswählen

from itertools import count
from operator import itemgetter

def sorted_refs(string):
    return map(itemgetter(1), sorted(zip(string, count())))


Schön kurz, oder? Und fast so komisch wie Perl-Code, dafür aber ohne komische Zeichen. :wink:

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder