LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 11-28-2008, 05:05 AM   #46
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454

Quote:
Originally Posted by ghostdog74 View Post
with Python 2.5
Code:
>>> d = dict()
>>> d['foo']['bar']=99
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'foo'
>>> from collections import defaultdict
>>> d = defaultdict(dict)
>>> d['foo']['bar']=99
>>> d
defaultdict(<type 'dict'>, {'foo': {'bar': 99}})
or for "nested" dictionaries
Code:
>>> class default_dict(dict):
...  def __missing__(self, key):
...   self[key] = value = self.__class__()
...   return value
...
>>> d = default_dict()
>>> d['foo']['bar']['doo']['dah'] = 777
>>> d
{'foo': {'bar': {'doo': {'dah': 777}}}}

i think it also can be done using setdefault albeit a bit more effort, or does it?

Code:
>>> class auto_dict(dict):
...  def __getitem__(self, key):
...   return self.setdefault(key, self.__class__())
...
>>> d = auto_dict()
>>> d["foo"]["bar"]["baz"] = 42
>>> d
{'foo': {'bar': {'baz': 42}}}
Reference: here
OK, so this is more or less like in Perl, albeit introduced recently.

What about multidimensional arrays ?
 
Old 11-28-2008, 05:23 AM   #47
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
Quote:
Originally Posted by Sergei Steshenko View Post
What about multidimensional arrays ?
not sure what you mean. you can provide a use case.
If you are talking about matrixes, Python has modules for that, eg NumPy.
 
Old 11-28-2008, 05:53 AM   #48
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by ghostdog74 View Post
not sure what you mean. you can provide a use case.
If you are talking about matrixes, Python has modules for that, eg NumPy.
So, one can't write this way:

Code:
sergei@amdam2:~/junk> cat -n ./md_array.pl
     1  #!/usr/bin/perl -w
     2
     3  use strict;
     4
     5  my @array;
     6
     7  $array[0][1][2] = 123;
     8
     9  warn "\$array[0][1][2]=$array[0][1][2]";
sergei@amdam2:~/junk> ./md_array.pl
$array[0][1][2]=123 at ./md_array.pl line 9.
in Python itself ?
 
Old 11-28-2008, 07:14 AM   #49
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
Quote:
Originally Posted by Sergei Steshenko View Post
So, one can't write this way:
in Python itself ?
eg
Code:
>>> x = [ [ ['1', '2'] ] ]
>>> x[0][0][1]
'2'
>>> x[0][0][1]="two"
>>> x
[[['1', 'two']]]
This requires defining the dimensions first before using.

you can also create so called "multidimension arrays",using dictionaries.
Code:
>>> x={}
>>> x[0,1,2]=1
>>> x
{(0, 1, 2): 1}
any objections?
 
Old 11-28-2008, 05:42 PM   #50
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by ghostdog74 View Post
eg
Code:
>>> x = [ [ ['1', '2'] ] ]
>>> x[0][0][1]
'2'
>>> x[0][0][1]="two"
>>> x
[[['1', 'two']]]
This requires defining the dimensions first before using.

you can also create so called "multidimension arrays",using dictionaries.
Code:
>>> x={}
>>> x[0,1,2]=1
>>> x
{(0, 1, 2): 1}
any objections?
Before I object, I would like to know how you'll deal with a more complex
example:

Code:
sergei@amdam2:~/junk> cat -n ./md_array.pl
     1  #!/usr/bin/perl -w
     2
     3  use strict;
     4
     5  my @array;
     6
     7  $array[0][1][2] = 123;
     8  $array[3][4][5] = 456;
     9
    10  warn "\$array[0][1][2]=$array[0][1][2]";
    11  warn "\$array[3][4][5]=$array[3][4][5]";
sergei@amdam2:~/junk> ./md_array.pl
$array[0][1][2]=123 at ./md_array.pl line 10.
$array[3][4][5]=456 at ./md_array.pl line 11.
.

And I want exactly the same index triplets that I have: [0][1][2], [3][4][5].
 
Old 11-28-2008, 07:56 PM   #51
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
Quote:
Originally Posted by Sergei Steshenko View Post
Before I object, I would like to know how you'll deal with a more complex
how is it more complex? $array[3][4][5] is just another location in memory.
Code:
x={}
x[3,4,5] = 456
x[0,1,2] = 123
 
Old 11-28-2008, 08:20 PM   #52
geek_man
Member
 
Registered: Nov 2007
Distribution: Fedora 7, Fedora 9, Solaris 10, Mac OS X, RHEL5
Posts: 71

Rep: Reputation: 15
I think Perl is better than Python. It is very useful and powerful, you can do a lot of things and it executes very fast.
I programm in Perl with vi.
 
Old 11-28-2008, 08:34 PM   #53
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
Quote:
Originally Posted by geek_man View Post
I think Perl is better than Python.
How long have you programmed in Python to make you say that.

Quote:
It is very useful and powerful, you can do a lot of things and it executes very fast.
I programm in Perl with vi.
please substantiate your statement that "Perl is better than Python" with actual FACTS. If you only based your comments on "it can do a lot of things and "executes very fast", then I can tell you they both can do a lot of things and can run programs pretty fast.
 
Old 11-28-2008, 10:17 PM   #54
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by ghostdog74 View Post
how is it more complex? $array[3][4][5] is just another location in memory.
Code:
x={}
x[3,4,5] = 456
x[0,1,2] = 123
Is this a hash (I think hashes are called dictionaries in Python) or an array ?
 
Old 11-28-2008, 10:49 PM   #55
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
Quote:
Originally Posted by Sergei Steshenko View Post
Is this a hash (I think hashes are called dictionaries in Python) or an array ?
yes, its called a hash in Perl, a dictionary in Python, or an associative array in awk. In fact, associative arrays are used to implement "multidimension" arrays much of the time.
Code:
awk 'BEGIN{
  foo[5,12] = "value"
}
 
Old 11-28-2008, 10:57 PM   #56
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by ghostdog74 View Post
yes, its called a hash in Perl, a dictionary in Python, or an associative array in awk. In fact, associative arrays are used to implement "multidimension" arrays much of the time.
Code:
awk 'BEGIN{
  foo[5,12] = "value"
}
Code:
sergei@amdam2:~/junk> cat -n ./md_array.pl
     1  #!/usr/bin/perl -w
     2
     3  use strict;
     4
     5  my @array;
     6
     7  $array[0][1][2] = 123;
     8  $array[3][4][5] = 456;
     9
    10  warn "\$array[0][1][2]=$array[0][1][2]";
    11  warn "\$array[3][4][5]=$array[3][4][5]";
    12
    13  warn "\$array[3][4]=$array[3][4]";
sergei@amdam2:~/junk> ./md_array.pl
$array[0][1][2]=123 at ./md_array.pl line 10.
$array[3][4][5]=456 at ./md_array.pl line 11.
$array[3][4]=ARRAY(0x8194e70) at ./md_array.pl line 13.
As one can see from the above, Perl does _not_ use hashes to implement multidimensional arrays - see the

$array[3][4]=ARRAY(0x8194e70) at ./md_array.pl line 13.

line.

Emulation through hashes means performance hit.

Is there a direct (array) implementation ? Again, I need the exact two triplets [0][1][2], [3][4][5] to be present.
 
Old 11-29-2008, 12:48 AM   #57
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
Quote:
Originally Posted by Sergei Steshenko View Post
[CODE]sergei@amdam2:~/junk>
Is there a direct (array) implementation ? Again, I need the exact two triplets [0][1][2], [3][4][5] to be present.
whether [0][1][2] or [3][4][5] or [3][4], they are just memory locations, or rather, indexes that help you get to a memory location. A key of a hash/dictionary does the same thing. If you want, i can always write
Code:
a["[0][1][2]"]="value"
and if a[3][4] is not defined, i can define it
Code:
a.setdefault("[3][4]")
In the end, there's really not much a difference between what an array or a hash is (to me). They are just plain memory spaces for you to store values in. Thus, no such thing as "multidimension" .


well, still if what i have shown about my views on things so far doesn't appeal to you, you are always welcome to seek expert opinions/answers at comp.lang.python. I am sure someone will answer your questions. After all, I am a just simple person with a simple mind.
 
Old 11-29-2008, 04:34 AM   #58
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by ghostdog74 View Post
whether [0][1][2] or [3][4][5] or [3][4], they are just memory locations, or rather, indexes that help you get to a memory location. A key of a hash/dictionary does the same thing. If you want, i can always write
Code:
a["[0][1][2]"]="value"
and if a[3][4] is not defined, i can define it
Code:
a.setdefault("[3][4]")
In the end, there's really not much a difference between what an array or a hash is (to me). They are just plain memory spaces for you to store values in. Thus, no such thing as "multidimension" .


well, still if what i have shown about my views on things so far doesn't appeal to you, you are always welcome to seek expert opinions/answers at comp.lang.python. I am sure someone will answer your questions. After all, I am a just simple person with a simple mind.
We are discussing all this in the light of power/weakness of Perl/Python.

I understand that logically multidimensional array can be implemented through hashes, and off the top of my head TCL does it this way - for example.

However, doing this is performance hit - not in favor of Python.

And the necessity to do 'a.setdefault("[3][4]")' is also not in favor of Python - as I said, a more powerful language is the one requiring less effort from programmer.

As we were shown, only recently Python gained autovivification of references - it was present in the very first release of Perl 5 - more than 10 years ago.

I still do not see decent multidimensional arrays.

Python is a more modern than Perl language ? In what ?
 
Old 11-29-2008, 05:44 AM   #59
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
Quote:
Originally Posted by Sergei Steshenko View Post
We are discussing all this in the light of power/weakness of Perl/Python.
no, i am not. you are the one who had that idea . I am only showing how the same thing can be achieved in another language, which maybe you are not really familiar with. With respect to comparing languages, i stand neutral.

Quote:
However, doing this is performance hit - not in favor of Python.
may i know where you are rushing to? also, I have already told you there are modules such as NumPy in Python that supports multidimension arrays more efficiently.

Quote:
And the necessity to do 'a.setdefault("[3][4]")' is also not in favor of Python - as I said, a more powerful language is the one requiring less effort from programmer.
so just what does $array[3][4]=ARRAY(0x8194e70) mean? Does Perl "initialize" or rather allocate some memory at the backend dynamically?
If that's the case, what's wrong with setdefault? It basically do the same thing. Just why i said, the term "powerful" is very subjective to each individual. Why is it requiring less effort from programmer considered powerful? What is less effort? Is it reduction of programming/development time? Less effort in deciphering what your code means to another person?? So what exactly is "less effort"?

Quote:
As we were shown, only recently Python gained autovivification of references - it was present in the very first release of Perl 5 - more than 10 years ago.
and why do you think there is Perl 6 ? Isn't that an improvement to Perl 5? Improvement is part and parcel. What's there to "argue" about?

Quote:
I still do not see decent multidimensional arrays.
well, have you posted to comp.lang.python and ask the experts there why?

Quote:
Python is a more modern than Perl language ? In what ?
from where did you get that notion?

Lastly, i see no point in continuing this conversation any longer as its getting OT and pointless. So this will be the last post.

Last edited by ghostdog74; 11-29-2008 at 05:46 AM.
 
Old 12-03-2008, 08:20 AM   #60
acerimusdux
LQ Newbie
 
Registered: Aug 2004
Posts: 12

Rep: Reputation: 0
Quote:
Originally Posted by Sergei Steshenko View Post
You didn't answer my question asked using the example with two "C" functions I've written - one of them calculating a * b + c, the other - x * y + z - my Perl code does not pose such a question, and it's good IMO since the question is irrelevant, your Python code does pose such a question.
I didn't answer your question because it was, as you point out, irrelevant. It also had nothing to do with my code. Real world, though, best practice would be to use descriptive names, like length, width, and height; the machine isn't going to care what you call them or if you name them at all, it's your human readers you need to worry about understanding it.

If you want to really have some benefit from functional techniques, you also need to think about modularity, maintainability, and re-use. If you have to make any changes to that procedure as you've modeled it, you are going to have to modify both the procedure itself (adding or changing sub routines), and the calling routine. If you wanted to reuse some of that, elsewhere, for a similar operation, with minor changes, you would probably have to copy it and duplicate it, as it was not written in a generic fashion. Anonymous functions mean you can't call them from elsewhere. Unneeded nesting means if you decide you want the addition, but not the multiplication, you can't get to subroutine Z without going through X and Y first.

But, in any case, that is all about coding style, and nothing to do with the language used. My main complaint with this thread is all of the misinformation in here about the Python language.

Quote:
Originally Posted by Sergei Steshenko View Post
"My" approach/code does not have this name collision problem _by construction_, i.e. the only name used ($result) is scoped and export/import is implemented anonymously, thus avoiding the problem altogether.
No, if you understand the scoping rules you are using, you should understand that all you are doing is reusing the name. When you call "my $result" in three different scopes, that is creating three separate $result variables (one local to each subroutine). Same thing when you call my $sub three times. This is purely a matter of programmer choice, nothing to do with any advantages of the languages (in Python, lexical scoping is the default, no "my" needed). At any rate, there are many times where using unique variable names is going to make for greater clarity than re-using the same names from the enclosing scope.

Quote:
Originally Posted by Sergei Steshenko View Post
The last, but not least. Your code is not Python as such - it's Python plus an external module. My code is pure Perl, i.e. I've used only the language.
I think you missed my point. The only reason for using the library, was to accomplish what you appeared to attempting to do in Perl, somewhat unsuccessfully. After all, you named the file "partial"--which implies that you were trying to demonstrate partial functions.

Of course I could have done it your way without any library usage. I just didn't see the point. It would have looked something like this:

Code:
def sub(x):
    result = x
    def sub(y,result=result):
        result = result * y
        def sub(z,result=result):
            return result + z
        return sub
    return sub


for x in [1,2]:
    xsub=sub(x)
    for y in [3,4]:
        ysub=xsub(y)
        for z in [5,6]:
            zsub=ysub(z)
            print x, y, z, zsub
Really the only differences there are minor idioms related to the individual language. In Python, classes, functions, object instances, and modules all have their own namespace. Conditional blocks like for and while loops don't. When you want different behavior from the default, you just have to be explicit about it.

All default behaviors will have to be over-ridden in some case. Perl likewise has defaults that you would have to override when you want different. The use of the my keyword in your code is in places where you want lexical scoping rather than the default (which in Perl is global--not good if you are concerned about side-effects). Your sample code also takes advantage of Perl's subroutines accepting arguments by default (what if you didn't want it to?) and returning the last calculated value by default (what if you didn't want that value returned?).

But as for what that code actually does, it is semantically no different than this (aside from the printing):

Code:
sub=lambda x: lambda y: lambda z: (x,y,z,x*y+z)
D=[[sub(x)(y)(z)] for x in [1,2] for y in [3,4] for z in [5,6]] 

>>>for line in D: print(line)

... 
[(1, 3, 5, 8)]
[(1, 3, 6, 9)]
[(1, 4, 5, 9)]
[(1, 4, 6, 10)]
[(2, 3, 5, 11)]
[(2, 3, 6, 12)]
[(2, 4, 5, 13)]
[(2, 4, 6, 14)]
>>>
Note that I am not calling that function with three arguments, I am calling it each time with one argument (with the returned function being used to call the next).

As for the truly functional way to do this, assuming that these multiplication and addition operations are meant to represent far more complex user defined operations (obviously there's no need for separate code blocks at all if all we are doing is using built-ins), my approach would still be similar, but with more generic reusable functions defined for those operations. For example, use function composition:

Code:
def add(x,y):
    return x+y
 
def multiply(x,y):
    return x*y
 
D=[[[x],[y],[z],[add(multiply(x,y),(z))]] for x in [1,2] for y in [3,4] for z in [5,6]]
Or, if you prefer:

Code:
>>> def add(a):
...     def result(b):
...        return a + b
...     return result
... 
>>> def multiply(a):
...     def result(b):
...         return a * b
...     return result

>>> D=[[[x],[y],[z],[(add(multiply(x)(y))(z))]] for x in [1,2] for y in [3,4] for z in [5,6]]

>>> for line in D: print(line)... 
[[1], [3], [5], [8]]
[[1], [3], [6], [9]]
[[1], [4], [5], [9]]
[[1], [4], [6], [10]]
[[2], [3], [5], [11]]
[[2], [3], [6], [12]]
[[2], [4], [5], [13]]
[[2], [4], [6], [14]]
As you can see, there is certainly no barrier here to functional programming. Functions in Python are first class objects, you can pass them as parameters, or as return values. You can nest them as you like, you have full support for recursive functions, you have full support for closures, you have lazy evaluation of (boolean) conditionals, you have strong support built in for iterators, generators, sequences, and list comprehensions, a nice collection of built-in higher order functions, and now "decorators" which behave similarly to macros.

Finally, wrt the discussion on arrays, one could call the list of lists demonstrated above an array. I wouldn't. But, they can be accessed witht he D[6][3] type notation, and if all you are interested in is retrieving and storing data, then dictionaries, lists, and tuples will do fine. Tuples are immutable lists; if values will be stored and not changed much, the tuple will be quick. Lists are mutable, but good if you will be writing as much as reading. Dictionaries are hash tables, which basically require an immutable type for keys (integers, strings, or tuples) but can hold any types as values. That's probably the most efficient way to store and retrieve data (especially mutable objects).

But, if you really need an array of 3 or more dimensions, or are planning on doing any numeric array calculations, such as multiplying or dividing matrixes, etc, you should use the array type from the numeric python library:

from numpy import array, arange

Those will do most anything you can think of with arrays (and not just for numbers, good for all data types).

All that said, I wouldn't be one to say Python is the "more powerful" language; on the contrary I think hw-tph pretty much nailed it back on page one:

Quote:
Perl vs Python. Python is a much more modern language, but Perl might a tad more versatile. It is however ugly and unstructured (rather the opposite of Python).
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Best Programming Language for an Old Programmer falcon56215 Linux - General 5 12-22-2007 01:40 PM
LXer: Software tools detect bugs by inferring programmerís intentions LXer Syndicated Linux News 0 07-07-2006 09:54 PM
Programmer/System's Analyst tools Citizen Bleys Programming 0 01-16-2002 05:19 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 07:42 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration