2

I am python beginner, so far I have read that python does not have references, if this is true what is the equivalent of following perl code in python?

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;

my @grps = qw/grp1:1:2:3 grp2:1:2:3 grp3:1:2:3/;

# CREATES AN ARRAY OF REFERENCES TO ARRAYS - AoR2A
my @agrps;
foreach (@grps){
  push @agrps, [split(":")];
}

# CREATES AN HASH OF REFERENCES TO ARRAYS (REFERENCES ARE THE SAME AS THEY ARE IN AoR2A ABOVE)
my %hgrps;
foreach (@agrps){
   $hgrps{"$_->[0]"} = $_;
}

# THE ELEMENTS CAN BE THEN ACCESSED EITHER VIA ARRAY OR HASH SYNTAX
$hgrps{"grp3"}->[3] = "NEW VALUE 3rd INDEX";
$agrps[2]->[2] = "NEW VALUE 2nd INDEX";

print Dumper @agrps;
print "\n";
print Dumper %hgrps;

The output of above script is following:

$VAR1 = [
          'grp1',
          '1',
          '2',
          '3'
        ];
$VAR2 = [
          'grp2',
          '1',
          '2',
          '3'
        ];
$VAR3 = [
          'grp3',
          '1',
          'NEW VALUE 2nd INDEX',
          'NEW VALUE 3rd INDEX'
        ];

$VAR1 = 'grp3';
$VAR2 = [
          'grp3',
          '1',
          'NEW VALUE 2nd INDEX',
          'NEW VALUE 3rd INDEX'
        ];
$VAR3 = 'grp1';
$VAR4 = [
          'grp1',
          '1',
          '2',
          '3'
        ];
$VAR5 = 'grp2';
$VAR6 = [
          'grp2',
          '1',
          '2',
          '3'
        ];
Wakan Tanka
  • 7,542
  • 16
  • 69
  • 122

1 Answers1

3

Perl needs references for two reasons:

  1. Complex (i.e. nested) data structures in a backwards compatible way. E.g. $hash{entry} = @array would have to keep assigning the array size to that entry, so using an array reference was an escape to use nested data structures: $hash{entry} = \@array.

    This problem does not exist in Python. Arrays and other data structures already are reference types, not value types.

  2. Indirection. For example in Perl we can do

    my $x = 1;
    my $ref = \$x; 
    $$ref = 42;
    # ($x == 42) is true
    

    This can be faked to a certain degree using arrays, the important part is not to use value types. For example we'd need two levels to change some value through a reference.

    x = [1]
    ref = [x]
    ref[0][0] = 42
    # (x is [42]) is True
    

    We need only one level if we just need a pointer that can refer to different things.

    It might be more readable if you use a Ref class:

    class Ref(object):
        def __init__(self, val):
            self.val = val
    
    ref = Ref(1)
    ref.val = 42
    

As your problem is centered around nested data structures, a translation of your code to Python would not require any “array references”. Plain lists will do.

grps = [...]
argps = list()
hrgps = dict()
for entry in grps:
    fields = entry.split(":") # split returns a list
    argps.append(fields)
    hrgps[fields[0]] = fields
amon
  • 57,091
  • 2
  • 89
  • 149
  • The more interesting question is does Perl need array and hash types as opposed to array and hash references (other than backward compatibility)? – socket puppet Apr 30 '14 at 01:13
  • @socketpuppet not really. Perl6 gets rid of references, at the expense of adding more contexts. Perl5 has void, scalar, and list context. Perl6 also has an item context in which an array behaves similar to Perl5's array references. Perl5 has also been drifting in that direction since then: Many builtins can now take array references where previously array variables were required, e.g. `push $array_ref, $value`. – amon Apr 30 '14 at 10:38
  • "Arrays and other data structures are already passed by reference." Python is *always pass-by-value*. Arrays and other objects in Python are not values, and cannot be "passed". All values in Python are pointers to objects. – newacct May 01 '14 at 09:14
  • @newacct thanks for pointing this out; using “pass by reference” was sloppy when I meant “reference type” (in contrast to value types). Btw, Python does have value types such as numbers. If they are implemented as pointers to objects, this isn't visible on the language level. – amon May 01 '14 at 10:23
  • 1
    @newacct: Python is "pass by name" it is neither "by reference" nor "by value" e.g., [In Python, why can a function modify some arguments as perceived by the caller, but not others?](http://stackoverflow.com/q/575196/4279). – jfs May 06 '14 at 16:31
  • @amon: Python numbers such as integers are ordinary Python objects; they are just immutable. – jfs May 06 '14 at 16:31
  • @J.F.Sebastian: Whatever you call it, it is the semantically pass-by-value. – newacct May 07 '14 at 00:31
  • 1
    @J.F.Sebastian: No, you are the one who is wrong. Rather than telling me to read something someone else wrote, you can defend your assertion yourself. Terms must be defined in ways that are consistent across languages. If you look anywhere on StackOverflow or on the Internet, Java is said to be pass-by-value. But the semantics of variables and assignment and passing are *exactly identical* between Java and Python. So both must be described with the same terms. – newacct May 07 '14 at 05:42
  • @newacct: 1. that someone is me :) 2. "wrong" in my comment means: your *statement* is wrong, not *you*. It is ok if you don't see the distinction. 3. What Java calls "pass by value", Ruby calls "pass by reference". I can prove that *objects* in Python are *not* passed by value. If you are interested; you can ask a [new question](http://stackoverflow.com/questions/ask). – jfs May 07 '14 at 08:43
  • @J.F.Sebastian: I have no question. My statement *is not wrong*, and I am responding to your comment saying it is. "Objects" in Python are not values, and cannot be "passed" at all. All values in Python are pointers to objects. So you are not "proving" anything. It's not up to a language to "call" it whatever it want. The term must be consistently defined to be meaningful. So either you say that Java, JavaScript, Python, Ruby, C, etc. are all pass-by-value, or you say that they are all something else. – newacct May 07 '14 at 18:39
  • @J.F.Sebastian: I can tell you my definition of pass-by-value. It is pass by value if simple assignment (`=`) to the parameter inside the function has no effect on the passed variable in the calling scope. According to this definition, the above languages are pass-by-value. If you have another definition, please state it. – newacct May 07 '14 at 18:41
  • 1
    @newacct: Wikipedia calls it [Call by sharing](http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing) (it is good because I don't know who else uses that term. So there is no wrong preconceptions). pass-by-value is [understood by many people as a process that involves **a copy**](http://stackoverflow.com/q/373419/4279) and CPython implementation uses it in that sense e.g., see `ctypes` source. But Python objects and their values are not copied during a function call. [objects and values have well-defined meaning](https://docs.python.org/3/reference/datamodel.html) in Python. – jfs May 07 '14 at 20:11
  • @J.F.Sebastian: It does involve a copy. It copies the pointer. You did not give a rigorous semantic definition. Making up new additional terms does not help people to understand what the original terms mean. Are you willing to come out and say that in Java when passing non-primitives, it's not pass-by-value? And that in C for pointer parameters it's not pass-by-value? – newacct May 07 '14 at 21:22
  • @newacct: show me one place in the Python language reference that says that "pointer is copied" during a function call -- hint: C is not the only implementation language and Python is not C. – jfs May 07 '14 at 21:30
  • @J.F.Sebastian: That was in response to your statement about "copying", which you did not define. It doesn't matter what a language spec says. It only matters what the semantics are. "Pass-by-value" and "pass-by-reference" are semantic terms, and should only be defined in terms of what a piece of code does, independent of language. It should not depend on vague concepts like "copying", "value", or "pointer". The definition I mentioned above is testable in terms of what semantics a code structure (assignment to a parameter) actually has, and is consistent with how it is used in C, C++, and Java – newacct May 08 '14 at 04:31