0
def make_to_str_list(list):
    for c in range(0, len(list)):
        list[c] = str(list[c])
    return list


def count_zeros(list):
    i = 0  # setting up the counter
    list = make_to_str_list(list)  # changes the list from a list of integers to a list of strings
    print(list)
    string = ''.join(list)  # changes list to a string
    print(string)
    while string.find('0') != -1:  # this is checking if there is a '0' in the string             
        del list[string.find('0')]  # this deletes the '0' from the string
        string = ''.join(list)  # this updates the string for the while loop
        print(string)
        i += 1  # adds a count
    return i  # returns the count


x = [1, 2, 0, 4, 0, 6, 7, 8, 9]
print(x)
print(count_zeros(x))
print(x)

Hello, I am rather new to python, and I have been experimenting with functions. The make_to_str_list function takes a list of numbers and replaces it with a string version of the number for use in the count_zeros function. I've had no issues with the make_to_str_list function. The problem I am having is that when I pass the list x into the count_zeros function, the function alters the list for the remainder of the code. The issue seems to lie with the while loop, as I can remove the loop and it no longer alters x for the entirety of the code. I have also noted that if I indent return i into the while loop, it also prevents the list x from being altered for the remainder of the code. However, I am assuming that is because it is prematurely stopping the function during the while loop, as the function returns a 1 instead of the 2 I am expecting. Here is what is printed from the code: [1, 2, 0, 4, 0, 6, 7, 8, 9] ['1', '2', '0', '4', '0', '6', '7', '8', '9'] 120406789 12406789 1246789 2 ['1', '2', '4', '6', '7', '8', '9'] The first print is from before the function to make sure that x = [1, 2, 0, 4, 0, 6, 7, 8, 9] The next four prints are from within the function. The print 2 is the returned value from the function, and the print ['1', '2', '4', '6', '7', '8', '9'] is the altered x list after the function has been called.

Daniel
  • 17
  • 2
  • "the function alters the list for the remainder of the code" - Of course. You told it to. There's a `del...` as the first statement in the loop, so of course it will alter `x`. – TigerhawkT3 Jun 25 '16 at 07:41
  • 1
    Also, you could replace all your code with `print(x.count(0))`. It would leave `x` unchanged, too. – TigerhawkT3 Jun 25 '16 at 07:46
  • Never ever call your variables as built-in functions/modules/whatever. Shadowing global names leads to all sorts of problems. – Eli Korvigo Jun 25 '16 at 07:49
  • Thank you very much Tigerhawk! I didn't realize .count existed. Thanks for the very quick response! – Daniel Jun 25 '16 at 07:50
  • Eli, what does it mean to shadow a global name? I am very new, and I don't quite understand that part. – Daniel Jun 25 '16 at 07:53
  • `list` is already bound to something when you start up the interpreter (a built-in function). If you name a new variable `list`, it becomes more difficult to access the object to which that name was originally bound. – TigerhawkT3 Jun 25 '16 at 07:54
  • That makes sense. Is there a way to alter my list `x` within the function but not have it translate to outside of the function? I noticed that you had flagged this as a duplicate question. I briefly read through it, but a lot of it went over my head. I don't want to take too much of your time. Would I be able to find my answer by reading that page's question and responses? – Daniel Jun 25 '16 at 08:02
  • 1
    One simple approach is to make a copy of x within the function like so: `x_copy = x[:]` – juanpa.arrivillaga Jun 25 '16 at 08:13
  • 1
    Or do it functional: `[char for char in string if char != "0"]`. It's also way faster than your quadratic-time algorithm, since it has linear time-complexity. – Eli Korvigo Jun 25 '16 at 08:18
  • 1
    Also, there really is no need to switch back and forth between lists of strings and strings for what you are trying to accomplish. – juanpa.arrivillaga Jun 25 '16 at 08:18
  • 1) If you don't want a function to mutate the passed-in list then you need to make a new list. One way is to create a copy of the passed-in list ; another way is to build a new list from scratch using `.append`, or a list comprehension. 2) As TigerhawkT3 said, the sensible way to do this task is via the `.count` method. But I guess there's nothing wrong with doing it the long way as an exercise in getting used to functions, loops, etc. – PM 2Ring Jun 25 '16 at 08:20
  • 3) But there's no need to keep converting back and forth between string and list like that. List objects don't have `.find`, but they do have `.index`, which is similar. And you can test if a list contains a particular item by using the `in` operator. 4) You may find this article helpful: [Facts and myths about Python names and values](http://nedbatchelder.com/text/names.html), which was written by SO veteran Ned Batchelder. – PM 2Ring Jun 25 '16 at 08:20
  • Eli, is that another approach to making a copy of `x` within the function? I'm not too good with `for` yet, and have been meaning to look into it further. – Daniel Jun 25 '16 at 08:21
  • @Daniel: Yes, Eli's suggestion is good. That construction is an example of a list comprehension. – PM 2Ring Jun 25 '16 at 08:22
  • @EliKorvigo Baby steps, Eli.I think for beginners it is important to cut your teeth at structured, imperative programming because it is the dominant paradigm and, at the very least, they are going to have to read a lot of code in that style and the idioms should become second nature. After one gets used to that, then you can start to explore the joys of python's functional constructs. – juanpa.arrivillaga Jun 25 '16 at 08:24
  • What is list comprehension? – Daniel Jun 25 '16 at 08:24
  • 1
    @Daniel it is a very useful way to construct lists. However, if I were you I would work on mastering for-loops before you begin to tinker around with list comprehensions. Also, take a look at my previous comment on how to easily make a copy using python slice notation for lists. – juanpa.arrivillaga Jun 25 '16 at 08:26
  • Good thinking, @juanpa.arrivillaga – PM 2Ring Jun 25 '16 at 08:27
  • Actually, a better question. Rather than wasting everyone's time with needless questions about simple things. Do any of you know a good place for beginners to learn this stuff? Currently, I have been using youtube which has been alright, but it's hard jumping from one content creator to another one. – Daniel Jun 25 '16 at 08:28
  • 1
    Please see [What tutorial should I read?](http://sopython.com/wiki/What_tutorial_should_I_read%3F) in the SO Python community wiki. – PM 2Ring Jun 25 '16 at 08:29
  • coursera and edx have tons of great python courses taught by top universities. Also, if you just want to master basic syntax, codecademy is a good way to practice, and the interactive nature seems to really help beginners. – juanpa.arrivillaga Jun 25 '16 at 08:29
  • Thanks for all the help :) Honestly, I wasn't expecting to get this much help. I'll definitely go through these resources. However, I'll have to save that for tomorrow. It is getting late for me, so I am going to head out. Have a nice night you all. – Daniel Jun 25 '16 at 08:32
  • 1
    Videos can be good, but you do really need to work through a properly-structured tutorial to get a solid grip on the language. Once you're confident with the basics you are welcome to ask questions in the [SO Python chat room](http://chat.stackoverflow.com/rooms/6/python). Anyone can visit chat, but you need 20 points of rep to post there. – PM 2Ring Jun 25 '16 at 08:33
  • Mark Lutz has an amazingly good book written specifically for beginners. It's called "Learning Python". It covers every aspect of the language and preaches very good practices. – Eli Korvigo Jun 25 '16 at 08:46

0 Answers0