Forum: PC-Programmierung [Perl] Arrays verschränken


von Vlad T. (vlad_tepesch)


Lesenswert?

hi,
gibts ne effiziente (ohne schleife) Möglichkeit Arrays zu verschränken 
(interleave)?

@a = (1,3,5,7);
@b = (2,4,6,8);

@c = someCoolPerlHack(@a,@b);

print '@c = ('.join(',',@c) .");\n";

-> @c = (1,2,3,4,5,6,7,8);

von (prx) A. K. (prx)


Lesenswert?

1
sub someCoolPerlHack
2
{
3
  return @_[map(($_&1) ? ($#_+$_)/2 : ($_/2), 0..$#_)];
4
}
Voraussetzung: beide Arrays sind gleich lang.

von Vlad T. (vlad_tepesch)


Lesenswert?

ahh,
Danke.

Ich liebe Perl Code. ;-)

von Daniel (root) (Gast)


Lesenswert?

>Ich liebe Perl Code. ;-)

Die Liebe macht gewöhnlich blind ;)
1
a=[0,2,4,6]
2
b=[1,3,5,7]
3
c=a.zip(b).flatten
4
=> [0, 1, 2, 3, 4, 5, 6, 7]

Wahlweise auch a.zip(b).flatten! um das Ergebnis nach a zu schreiben
Ich würde mal sagen schöner geht es nimmer^^

Die Pythonvariante ist auch sauberER als Perl
1
a=[0,2,4,6]
2
b=[1,3,5,7]
3
c=[]
4
[c.extend((x,y)) for x,y in zip(a,b)]
5
=>
6
[0, 1, 2, 3, 4, 5, 6, 7]

Prinzipiell funktioniert zip genauso, leider hat meines Wissens
Python noch keine builtin flatten Funktion.

von Vlad T. (vlad_tepesch)


Lesenswert?

Daniel (root) schrieb:
>>Ich liebe Perl Code. ;-)
>
> Die Liebe macht gewöhnlich blind ;)
>
>
1
> a=[0,2,4,6]
2
> b=[1,3,5,7]
3
> c=a.zip(b).flatten
4
> => [0, 1, 2, 3, 4, 5, 6, 7]
5
>
>
Häh? das ist doch nie und nimmer perl.
wo sind denn die $ oder @?
Der Punkt ist doch der concat-operator.

von Daniel (root) (Gast)


Lesenswert?

lol, richtig erkannt! Mein Fehler, hätte Ruby explizit erwähnen sollen.

Damit ich nicht ganz OT bin ...
>gibts ne effiziente (ohne schleife) Möglichkeit Arrays zu verschränken
>(interleave)?

Der Code von A.K enthält implizite Schleife in map Funktion.
Soll heissen, die Effizienz wird kaum gross unterschiedlich sein.
(meine Vermutung, da ich Perl interna zur Namensauflösung nicht kenne)

von (prx) A. K. (prx)


Lesenswert?

Daniel (root) schrieb:

> Der Code von A.K enthält implizite Schleife in map Funktion.
> Soll heissen, die Effizienz wird kaum gross unterschiedlich sein.

Natürlich. Aber jeder Code der mit Arrays oder Listen hantiert hat eine 
Schleife drin. Kannst dir allenfalls aussuchen wo und auf welcher Ebene.

Es ist auch nicht immer so einfach zu beantworten, welche Version einer 
Listenverarbeitung effizienter ist. Bei hinreichend grossen Arrays ist 
wohl jede Version auf Basis eines Funktionsaufrufs allein schon der 
Parameterübergabe und des Speichergeschubses wegen ineffizient, 
verglichen mit einer expliziten Schleife auf Hauptprogrammebene, die nur 
Skalare verarbeitet.

Ich würde es selbst auch nicht so implementieren. Das war einfach nur 
eine Anwort auf seine Frage, ob man das ohne explizite 
Schleifenprogrammierung hinbekommt.

von yalu (Gast)


Lesenswert?

Noch einmal kurz OT:

Daniel schrieb:

> Die Pythonvariante ist auch sauberER als Perl
> ...
> c=[]
> [c.extend((x,y)) for x,y in zip(a,b)]

Das ist nicht besonders schön, da man bei der List-Comprehension nur den
Seiteneffekt von extend nutzt und das eigentliche Ergebnis (in diesem
Fall eine Liste mit lauter Nones) zwar aufbauen, anschließend aber unter
den Tisch fallen lässt.

Es geht aber (rein funktional) bspw. so:
1
c = sum(zip(a,b),())

mit dem kleinen Schönheitsfehler, dass das Ergebnis keine Liste, sondern
ein Tuple ist. Ist tatsächlich eine Liste gewünscht, kann das Ergebnis
noch konvertiert werden:
1
c = list(sum(zip(a,b),()))

oder, wenn man möchte, schon vor dem Verketten:
1
c = sum(map(list,zip(a,b)),[])

Jetzt aber wieder zurück zu Perl, das ich zwar extrem cool finde, aber
zu wenig Ahnung davon habe, um intensiv mitreden zu können ;-)

von Vlad T. (vlad_tepesch)


Lesenswert?

naja, es wird die eigenart genutzt, dass bei als funktionsargument 
übergebenen Arrays, diese nicht als zwei arrays ankommen sondern als ein 
großes (@_), welches dann mit einem array indiziert wird, welches per 
map auf die Zahlen 0..@#_ (letztes Arrayelement) erzeugt wird

0..@#_
->
0, @#_/2, 1, @#_/2+1, 2, @#_/2+2, ..., @#_/2-1, @#_

clever

von Klaus W. (mfgkw)


Lesenswert?

irgendwo hatte ich mal gelesen, C und C++ wäre unleserlich.

von Kai G. (runtimeterror)


Lesenswert?

>irgendwo hatte ich mal gelesen, C und C++ wäre unleserlich.

Ich weiß nicht, ob Perl zu über- bzw. unterbieten ist:
http://de.wikipedia.org/wiki/Obfuscated_Perl_Contest

Ich halte /Brainf*ck/ für intuitiver ;)

von yalu (Gast)


Lesenswert?

Kai Giebeler schrieb:

> Ich halte /Brainf*ck/ für intuitiver ;)

Kein Problem! Für den sanften Umstieg von Brainf*ck auf Perl oder
umgekehrt gibt es multilinguale Programme wie das letzte Beispiel in
diesem Link:

  http://de.wikipedia.org/wiki/Just_another_Perl_hacker

von Kai G. (runtimeterror)


Lesenswert?

Autsch ;)

von (prx) A. K. (prx)


Lesenswert?

Ich habe im Grunde nur ein Denkschema verwendet, wie ich es von APL 
kenne, meiner ersten Programmiersprache: 
http://en.wikipedia.org/wiki/APL_(programming_language)#Examples

> irgendwo hatte ich mal gelesen, C und C++ wäre unleserlich.

Traumhaft lesbar im Vergleich zu APL. Dafür sind APL-Programme oft nur 
wenige Zeilen lang, wofür man anderswo ein paar Seiten schreibt.

von Daniel (root) (Gast)


Lesenswert?

Irgendwo hat sich in meine Erinnerung eingebrannt, dass was ich
gelesen hab. Und zwar, dass einige Editoren beim Perlcode Highlighting
aussteigen. War das nicht sogar emacs?
Wie auch immer, ich vermisse eine Spec, die die Sprache beschreibt.
Wenn Perl6 rauskommt, hoffe ich, dass es strukturierter wird.
Dann werde ich mir etwas Zeit nehmen und es mir anschauen.

von (prx) A. K. (prx)


Angehängte Dateien:

Lesenswert?

Sowas kann auch ausgesprochen trivial aussehen. Man macht aus den 2 
Arrays eine Matrix mit 2 Spalten und verkettet dann deren Elemente 
entsprechend ihrer Indexreihenfolge. APL, kommt diesmal sogar ganz ohne 
Sonderzeichen aus.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.