2

Currently learning python modules and functions and the task is to simply display a list without any built in functions (other than range() and str(), can't use slice expressions, list methods or string methods either.

So using this that we're not supposed to edit:

list1 = ['q', 'w', 'e', 'r', 't', 'y']
emptyList = []

string = my_string(list1)
print(string)
print(my_string(emptyList))

and this that I made myself:

def my_string(first_list)

    my_string = "List: "

    for x in range(len(first_list)):

        my_string += str(first_list[x]) + ", "

    return my_string[:-2]

currently outputs:

List: q, w, e, r, t, y
List

The correct output should be:

List: q, w, e, r, t, y
List:

The slice that i'm not supposed to use cuts off the final comma on the first list, however also takes of the colon on the second. How would I go about removing the final comma and keeping the colon without using a slice expression?

I'd normally ask my prac tutor but I don't have another lesson for another week

  • The pythonic way would be to use join - I guess that's not allowed either to make it artificially complex? – dornhege Jun 10 '14 at 12:45

6 Answers6

1

The straight-forward way is: Don't put the comma in in the first place.

Basically put a comma before each entry unless it's the first.

I'll leave the coding for you to learn.

dornhege
  • 1,500
  • 8
  • 8
1

The canonical way to deal with edge-cases is to specialize:

def my_string(first_list)
    my_string = "List: "

    for x in range(len(first_list)):
        my_string += str(first_list[x]) + ", "

    # Can only crop string if it has a trailing ", "
    if first_list:
        my_string = my_string[:-2]

    return my_string

There are of course better ways of dealing with this precise problem (eg. for item in first_list), but that's for later learning.


Note that += on strings (or any immutable sequence, like tuples) in a loop is bad and this is only remotely acceptable because this is a learning excercise.

Veedrac
  • 58,273
  • 15
  • 112
  • 169
  • Could you explain why is bad to do `+=` in a loop? Thanks – llrs Jun 10 '14 at 14:38
  • Basically [on bad days](http://stackoverflow.com/questions/24040198/cpython-string-addition-optimisation-failure-case) it can have [`O(n²)` performance](http://stackoverflow.com/questions/487258/plain-english-explanation-of-big-o) [read the second link first]. This is because each time you add strings it needs to rebuild *everything*. It's like building a house, but every time you add a brick you have to *rebuild the whole house*. Obviously that's a *bad* idea. – Veedrac Jun 10 '14 at 14:56
  • Oh, so the `+=` is O(n²). Thanks I hadn't read yet this questions and the answers are quite educative! – llrs Jun 10 '14 at 15:19
  • It's not quite that simple. I couldn't find a clear answer so I'll write one now. – Veedrac Jun 10 '14 at 15:27
  • 1
    http://stackoverflow.com/questions/24145155/why-is-addition-of-immutable-containers-in-a-loop-on%C2%B2/24145156#24145156 – Veedrac Jun 10 '14 at 15:38
1

You don't need to use a slice. Using mostly your own code, the following will work by putting a comma after every element unless it's the last element:

def my_string(first_list):

    my_string = "List: "

    for x in range(len(first_list)):

        my_string += str(first_list[x]) 
        if x != len(first_list) - 1:
            my_string += ", "

    return my_string

list1 = ['q', 'w', 'e', 'r', 't', 'y']
emptyList = []
string = my_string(list1)
print(string)
print(my_string(emptyList))

Having said that, I understand that this is an exercise but it's definitely not the best way to do this. Just for reference, a more Pythonic way to do this would be:

list1 = ['q', 'w', 'e', 'r', 't', 'y']
emptyList = []
print('List: {}'.format(', '.join(list1)))
print('List: {}'.format(', '.join(emptyList)))
s16h
  • 4,647
  • 1
  • 21
  • 33
1

Just "if" statement in the beginning and you won't need a lot of repeatable "if"'s

def my_string(first_list)
    my_string = "List: "
    if len(first_list) == 0:
        return my_string
    for x in xrange(len(first_list)):
        my_string += str(first_list[x]) + ", "
    return my_string[:-2]
1

You could try this (inspired by dornhege's answer):

def my_string(first_list)

    my_string = "List: "

    for x in range(len(first_list)):

        if x == 0:

            my_string += str(first_list[x])

        else

            my_string += ", " + str(first_list[x])

    return my_string
nicolas.leblanc
  • 588
  • 7
  • 27
1

The pythonic way would be to use str.join like so:

def my_string(lst):
    return "List: " + ", ".join(lst)

But since you are not allowed to use string methods, you have to emulate join by yourself.

Since join is pretty useful and generic, you might want to create a reusable function for it:

def my_join(items, sep):
     tmpstr = ''
     for item in items:
         if tmpstr:
             tmpstr += sep
         tmpstr += item
     return tmpstr

and use it via:

def my_string(lst):
    return "List: " + my_join(lst,", ")

If you are not even allowed to create helper functions on your own, then you have to combine the code of my_string and my_join into my_string, of course.

ch3ka
  • 11,792
  • 4
  • 31
  • 28