Tuesday, March 18, 2008

Python sucks!

All I want to do is to take a string, and pull the first character off of it in a function....

like this:

def pullchar(s):
"""pull a single character from the front of a string"""
c = s[0]
s = s[1::]
return c



Can python do this? Not really...

Why? Because there doesn't seem to be any way to pass a variable to a function...

WTF?

9 comments:

Albert Sweigart said...

You don't really need a function for a simple operation like this, as Python's language conventions can handle it just fine:

c, s = s[0], s[1:]

Adding a new function to do this may make your code more complicated. Of course, you might want a check to see if the string has a length of 2 or more, and so then a function would be good:

def pullchar(s):
    if len(s) >= 2:
        return s[0], s[1:]
    elif len(s) == 1:
        return s, ''
    else:
        return '', ''
c, s = pullchar(s)

You seem to be miffed that Python does not pass by reference for strings, but this is because Python has string immutability. String immutability is a design decision that makes a lot of sense for performance and multithreaded apps.

Of course, Python lets you convert an immutable string into a mutable list very easily:
s = 'Hello world!'
s = list(s)

Then you could pass this list of single characters by reference. But doing all of that doesn't improve performance or productivity. I think either of the two solutions is fine.

miked said...

Are you sure you don't want to just iterate over all characters in the string?

mystring = 'foo'
for character in mystring:
do_something(character)

Also, in your other post ("Python Rocks!") you mention you are trying to use this to process data files. In that case you might want to do something like:

f = open('hugin.pto', 'rb') # the 'b' is for binary mode, may not be necessary for your data

character = f.read(1)

while character:
do_something(character)
character = f.read(1)

regebro said...

Or:

>>> string = "abcdefgh"
>>> stack = list(string)
>>> stack.reverse()

Now, each time you want to pull one character out, you do:

>>> stack.pop()
'a'
>>> stack.pop()
'b'
>>> stack.pop()
'c'
>>> stack.pop()
'd'

etc.

Anonymous said...

Do you know why Python _really_ sucks? It has string immutability, but it doesn't compensate for this by giving you good tools for doing functional programming on strings. There's no string.reverse(), for example.

Anonymous said...

In [1]: s = 'toast'

In [2]: s[::-1]
Out[2]: 'tsaot'

Anonymous said...

It is way easier to understand string.reverse() than s[::-1] - python sucks

Anonymous said...

string.reverse() is a special case of very limited functionality.

[::-1] is just one use of the generic slicing operator. For example, [::-5] will give you every fifth character of the string in reverse order.

Anonymous said...

"String immutability is a design decision that makes a lot of sense for performance and multithreaded apps."

LOL! It does not make sense for performance at all. And Python sucks for multithreaded apps anyway. And even if the performance argument would hold, it does not make any sense for Python: Python has never been designed for runtime performance.

JiBB said...

While python strings don't have a reverse method, that fits with them being immutable. The analogous method on lists reverses them in place, which doesn't make sense for an immutable object. However, both strings and lists are iterable objects and so can be passed to the builtin reversed function (reversed('abc') returns 'cba'). This is the functional style approach that the 1st anonymous commenter wanted.

Blog Archive