Python Forum
Learning python specific syntax after using other scripting languages for years
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Learning python specific syntax after using other scripting languages for years
#1
Hello, I'm learning AI and if you're doing AI you need python it seems. I've long time used PHP, Javascript and occasionally bash for my job as a fullstack web developer. I'll first admit, I'm not liking Python, but perhaps part of that is because I don't really get the "why" of some of what it does. So maybe you friendly people would be willing to help me out. I'll be making comparisons to PHP a lot because that is what I am most familiar with and would like to achieve in Python.

First datastructures. In PHP you have an array. That array can hold anything and is manipulated by the same utility methods (which are functions not methods of some object). The closest I can find to PHP arrays in Python is a dictionary, but PHP arrays also maintain order and I guess dictionaries do not.

My first "Why" question is why is a scripting language, which are not strongly typed by design and one of the biggest selling points of a scripting language over a compiled language, having so many data structures as objects? You have tuples, lists, dictionaries, sets, counters, and probably more. What is the difference between a list or a set? Why do I have to memorize and understand this to stuff things into a loopable container and do stuff with it? It seems to overcomplicate things and make it hard to use.

My second "Why" question is why is there no standard looping? For any given of those data structures there seems to be 3-4 ways to loop over them, and people pick up different preferences on looping and it makes both reading and writing code harder because there isn't just one easy way to do it, there's 3-4 more difficult ways to do it. Example in PHP there is the for loop and the foreach loop. Most the time the foreach loop does anything you'd need with an array. It gives you the key, the value, and it can be told to do the value by reference instead of using a copy. Literally everything you'd need or want. With Python however you have to use enumerable, or type the name of the thing you're looping over and provide the index to access the value, or use range, or use some weird thing in brackets to do shortcuts on math that is hard to both understand and read. Why have 4 ways to do something, quality is better than quantity here you shouldn't have to wrap something in a function just to loop over it like this, so why?

My third "Why" question is why does it not convert things to be printable without converting types? If you try to print a string and an integer it fails with an error. This is making typing again, an issue, and now you need to convert the number to a string to print the two together or separate them with a , in the print statement rather than concatenating like you do in pretty much every other language I know of.


Here are some examples to go with my text to make it easier to understand what I'm getting at:
PHP example:
$a = array('one'=>2,3=>4,5=>'six');
foreach($a as $k=>$v) echo "$k:$v\n";
I don't even know how to do that in python or even if there's such a data construct that would handle it. I know the looping is going to be a pain and so is the printing :(

I mean which data structure would I use, sets, lists, dictionaries, counters, tuples?

And which of the looping methods do I use after that?

a = {'one':2,3:4,5:'six'} #doesn't this fail for some reason?
for item in a: #can't get index
    print(str(item) + "\n") #have to convert item to string, if it works?
for k,v in enumerate(a): #gets index but has to call a function...
    print(str(k) + ":" + str(v) + "\n") #have to convert to string?
for k in range(len(a)): #gets index but value has to be accessed and now you're calling two functions...
    print(str(k) + ":" + str(a[k]) + "\n") #have to convert to string?
And last we have this syntax for making shorthand loops, this would multiply each value by two and reassign it to the container so doesn't achieve the same things as above but maybe there's some way to make it print from this syntax I'm not sure...
a = [val * 2 for val in a]
I don't think it works with anything but lists but I don't know for certain. All I know is it seems very unintuitive to read and looks way out of place to me.

So, hope there's some nice people here that can explain why python is this way (even if it's just admitting it's silly it would help me feel a bit better about it). To be honest, everyone talks about how great and easy python is and should be taught to beginners but I find it very much complicates simple things for no apparent reason by reintroducing typing and making you have to call functions to even iterate over things :/
Reply
#2
I had withdrawal from C and C++ at first, but now, I never go back.

But I never was fond of PHP
Reply
#3
Quote:First datastructures. In PHP you have an array. That array can hold anything and is manipulated by the same utility methods (which are functions not methods of some object). The closest I can find to PHP arrays in Python is a dictionary, but PHP arrays also maintain order and I guess dictionaries do not.

Yes, in other languages or in general this is called a Hashtable.
A Hashtable don't save the order of elements.
In PHP this is an implementation detail aswell in Python. Since
Python 3.6 the implementation of dicts has been changed and the order
is now preserved, but developer should not relay on this implementation detail
until it's official in the language. If you want to preserve the order, you can use
collections.OrderedDict.

Example:

import collections
items = [('First', 1), ('Second', 2), ('third', 3)]
ordered_dict = collections.OrderedDict(items)
for key, value in ordered_dict.items():
    print('Key:', key, 'Value:', value)
Don't use a dict as "constructor" for OrderedDict.

Quote:I mean which data structure would I use, sets, lists, dictionaries, counters, tuples?
  • tuple: immutable, holds a sequence of elements
  • list: mutable, holds a sequence of elements, you can add new elements to the list
  • dict: mutable, fast hashtable lookup, no order
  • set: mutable, same as dict, but without values. It's from set theory in math.

Then you've some additional mixed types, which are based on the atomic types.
For example: collections.OrderedDict is a mix of dict and list.

All data types, which are containers, can used for iteration. You can iterate over: tuple, list, dict, set, OrderedDict.
If you iterate over a dict or a set, there is no guarantee for order.

Data types, which are hash table based (dict, set), can hold only objects as keys, which are hashable. A list is not hashable, because it's mutable.


Indexing: If you want to get indexes in a loop, enumerate is the pythonic way. The additional call don't cost much. I think it's implemented in C as a generator.

Printing obejcts: You can print all objects without type conversion. If you have already a str object, just print it. If you call the built in function str on an object, which is already a str, you'll get the same object back. Behind the scenes the print function call the __str__ method of an object. If this method does not exist, it calls __repr__ which stands for representation. General you want to use string interpolation. Look here: https://pyformat.info/

Quote:
a = [val * 2 for val in a]
This gives you a list back.
If you want to print the whole object, just use print(a).
Then you'll get the representation of the list, which can be evaluated in Python.
If you want an output line by line, you can use a for loop:

for element in a:
    print(element)
or you can use the print function inside the list comprehension, but this is not used often:

a = [print(val * 2) for val in a]
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#4
Quote:why does it not convert things to be printable without converting types?

Unlike a lot of languages, Python doesn't let you add numbers to strings and vice versa. The following is simply not supported:

s = "Hello " + 5
I can't give you the Pythonic answer for this(i.e., why the designers chose not to support it). Personally, I don't like implicit casting and from my own experience, using a wide range of languages, I prefer it this way.

Instead Python supports string formatting.
https://docs.python.org/2/library/string.html
https://docs.python.org/2/library/functions.html#print

So here's your code:
print(str(k) + ":" + str(v) + "\n")
Which is creating a string by concatenating the various pieces and if 'k' or 'v' are integers, it won't work.

It can be done in two ways:
print("%s:%s"%(k, v))
print("{0}:{1}".format(k,v))
Personally, I find the latter easier to read. Note that I didn't include the '\n', that's included automatically, unless you specify something different with the end keyword argument.

You can also simply print integers without effort:
x = 5
print(x)
Reply
#5
Note. This is in python 3. if you using python 2. I would suggest you jump over to python 3.

1. Python is strongly type but it all underneath the hood.

2. You use the best loop for the job. You should never delete an item in a for loop.
but in a while loop you can make adjustments.

example
# Python is strongly type. You just don't see it
def myfunction():
	pass
	
a = {}
b = []
c = (1,1)
	
print(type(1))
print(type('word'))
print(type(0.5))
print(type(a))
print(type(b))
print(type(c))
print(type(c[0])) # first element
print(type(myfunction))

print()
a = {'one': 2, 3:4, 5:'six'}
for key in a: # just loop over keys
	print(key)

print()	
for key, value in a.items(): # iter over (key, value)
	print(key, value)
	
print()	
for key in a.keys(): # iter of keys
	print(key)

print()	
for value in a.values(): # iter over values
	print(value)
	
a = dict([(key, value * 2) for key, value in a.items()])
print(a)
99 percent of computer problems exists between chair and keyboard.
Reply
#6
Quote:It can be done in two ways:
Actually three, now that f-string exists in python 3.6

print(f'{k}:{v}')
Reply
#7
If you really want things to be a specific way. You can make your own types.
# if you really want to string + int
# just make an override
class MyString(str):
	def __add__(self, value):
		if isinstance(value, (int, float)):
			return MyString(str.__add__(self, str(value)))
		else:
			return MyString(str.__add__(self, value))
			
a = MyString('Hello') + 5
a = a + 7
print(a)
99 percent of computer problems exists between chair and keyboard.
Reply
#8
Also, you can iterate over a str type ( strings ).

So:
for char in 'hello':
    print(char)
Output:
h e l l o
This is the Python way. This is why I love Python. You have seen it in the previous posts I suppose. I really like how some people put an effort to explain something. Bravo to @DeaD_EyE!

A lot of people who comes from other languages are doing this:
s = 'hello'
for char in range( len (s)):
    print(char[0])
It's ugly, clumsy and hard to read. I've seen it in a book teaching Python. Dodgy  Don't remember the title. And in the articles over the web too.

Use the forum to its full potential. Look at the code in the tutorials.

Welcome!
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Reply
#9
Thank you for all your replies, it helps quite a bit. I posted this thread with a bit of trepidation, I'm so used to being met with hostility for having my own perspective on things especially if that is critical of someone else's method or favorite language. More than anything that helped me be more welcoming of python.

Reply to DeaD_EyE:

Quote: If you want to preserve the order, you can use collections.OrderedDict.

This helps quite a bit as does the rest of your very thorough post thank you :)

Quote:tuple: immutable, holds a sequence of elements
list: mutable, holds a sequence of elements, you can add new elements to the list
dict: mutable, fast hashtable lookup, no order
set: mutable, same as dict, but without values. It's from set theory in math.

This also helps, immutable types is a weird concept to me but I can understand it'd be useful for optimization.

Quote:Indexing: If you want to get indexes in a loop, enumerate is the pythonic way. The additional call don't cost much. I think it's implemented in C as a generator.

This is still a weird choice to me but I guess we can't always have what we want, hopefully one day python can have a powerful foreach loop as it is in many ways my love letter to PHP.

Thank you again for your detailed post I learned a lot and it helped me not feel angst toward python so much, I have to use it and I don't want to be miserable while doing it.

Reply to mpd:
Thank you for your reply as well as others!

Quote:Unlike a lot of languages, Python doesn't let you add numbers to strings and vice versa. The following is simply not supported:
This will just be something I have to accept about python I suppose. I enjoy implicit casting, it saves me having to deal with details that don't matter for my implementation. To me types are reserved for compiled languages, which you should use when run speed and optimization are important. Scripting languages are dynamically typed so that data and memory management aren't on the table, the opposite of compiled languages which is part of every variable and function you write. There's no real reason for me to have to change data types of a var or container if the language manages it for me, otherwise, unless you just like extra unneeded work. There is some small argument for data integrity checks but when and if that matters scripting languages can still check types.

Reply to Windspar:

Thank you for this extensive example I will run it in Jupyter later and check it out :)

I would like to say that all scripting languages are strongly typed under the hood, they have to, in order to store things in memory, etc. It's just with interpreted/scripting languages usually typing is dynamically done so you don't have to manage how it is stored in memory.

The fact you can modify or extend types is also pretty neat though I know javascript makes extensive use of that in some libraries so it's something I have seen before :)

The printing stuff reminds me a lot of sprintf in C languages and PHP has both a sprintf and printf that behave similar. I'm just so used to being able to put variables inside strings it's one of my favorite features I haven't seen anywhere else but php, except maybe perl which php has a lot of ideas from.

Thank you again for your replies really appreciate it :D

Reply to wavic:
That is also useful to know thank you. I recall something similar in php but it's been a while since I used it, (I do use {} to access specific characters sometimes though).

Reply to Larz60+:
Thank you for your replies too, I'm sad to hear you never enjoyed PHP but I guess I don't have much room to talk since I'm here to learn python and I wouldn't expect everyone to share my opinion regardless :)

The f-string example is neat I will try that out.



These replies were more than I expected thank you for taking the time to answer some of the "why" and explain things from more experienced python users point of view. Every language will have it's own unique strengths and weaknesses afterall and it's own way of thinking, and while I might not always be a fan of each and every difference and consider some steps backward I can at least learn to utilize it and be effective with it in no small part thanks to helpful people like you guys, so thanks.
Reply
#10
(Dec-12-2017, 12:30 AM)Arcs Wrote: hopefully one day python can have a powerful foreach loop as it is in many ways my love letter to PHP

Not quite sure you understand that python HAS it...
i.e. your example in OP, is the same as printing key, value pairs from dict as already shown in previous posts, but anyway

PHP
$a = array('one'=>2,3=>4,5=>'six');
foreach($a as $k=>$v) echo "$k:$v\n";
Python
a = {'one':2,3:4,5:'six'}
for key, value in a.items():
    print('{}:{}'.format(key, value))
now if you want also the index, then you need enumerate
same apply for any other iterable. Actually this is the pythonic way, not using indexes
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Converting days to years in loop while computing values across grid cells Lightning1800 2 2,643 May-15-2018, 08:44 PM
Last Post: Lightning1800

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020