Create a list of even numbers from a list

Trying to create a list of even numbers from a list but receiving an error. Here’s what I have:
def myfunc(*args):
myfunc=[2,3,4,6,8,101,103,111,120,124]
listofitems =
for x in myfunc:
if x % 2 == 0:
# Output
listofitems.append(x)
return listofitems

Correct me if I’m wrong, but I think that what you’re trying to do is this:

def list_even(x):
    even = []
    for n in x:
        if not n %2:
            even.append(n)
    return even

numbers = [2,3,4,6,8,101,103,111,120,124]

print(list_even(numbers))

If you’re unsure about what I’ve done there, then feel free to ask questions.

Thank you, This is helpful. Attempted a variation

def myfunc(x):
list_even =
for n in myfunc:
if not n %2:
list_even.append(n)
return list_even

numbers = [2,3,4,6,8,101,103,111,120,124]

print(list_even(numbers))

not running. I’m getting an error message “list_even is not defined”.

Curious why the numbers list is shown below the loop?

Also, please keep in mind while I’m an expert VBA programmer I’m in my first week of Python.

You’re welcome.

Would you do something, please?

Code blocks are formatted with backtics, like this:

```python
# code goes here
```

Could you edit your last post and enclose the code, as in the above example, so that it’s easier to read and understand.

Thanks.

def myfunc(x):
‘’‘’‘’‘‘list_even =
‘’’’‘’‘‘for n in myfunc:
‘’’’‘’‘’‘’‘’‘’‘if not n %2:
‘’’‘’‘’‘’‘’‘’‘’‘’‘’‘list_even.append(n)
‘’’‘’‘’'return list_even

numbers = [2,3,4,6,8,101,103,111,120,124]

print(list_even(numbers))

Is this better

No, not really.

Here’s a better example:

```python
def list_even(x):
    even = []
    for n in x:
        if not n %2:
            even.append(n)
    return even

numbers = [2,3,4,6,8,101,103,111,120,124]

print(list_even(numbers))
```

Not a worry; I think I can work with it.

You’re using myfunc as both the name of your function and the operator for the for loop; not good.

Also, to call the function, you need to use the name of said function. Maybe I confused you by including it in the print function call.

So, you’ll need print(myfunc(numbers))

The reason I named the function list_even is that the name is descriptive of what the function is doing.

The name I’ve used, such as x, was also not too helpful; sorry.

What that does: the x in the function holds the list of numbers that has been passed to it, as in list_even(numbers) The list of numbers is passed to the function, which can use that list, which is held in the a local variable, x. You can see this if you put a print call in the function:

def myfunc(x):
    print(x)

numbers = [2,3,4,6,8,101,103,111,120,124]
myfunc('Hello')
myfunc(101)
myfunc(numbers)

By Dave via Discussions on Python.org at 15Sep2022 22:36:

def myfunc(x):
‘’‘’‘’‘‘list_even =
‘’’’‘’‘‘for n in myfunc:
‘’’’‘’‘’‘’‘’‘’'if not n %2:

I don’t think that’s what Rob meant. He was asking you to “fence” your
code with a line of triple backticks top and bottom, like this:

 ```
 your code
 goes here
 ```

This preserves the indentation and punctuation in the code, making it
much easier for the reader. The same for output or error messages.

Note: on my keyboard the backtick is at top left on the key with the
tilde (~). The “smart quotes” left opening quote mark is not a
backtick. On the web forum there’s a marker to insert code if you’d
prefer that.

Cheers,
Cameron Simpson cs@cskk.id.au

By Rob via Discussions on Python.org at 15Sep2022 22:38:

   if not n %2:

I just wanted to chime in here about not n % 2, to discourage it. It
would be better to write:

 if n % 2 == 0:

which precisely expresses what you’re testing: whether the remainder is
0 when you divide by 2.

What Rob’s doing, while it works, depends on a number of Python specific
things.

The first is that applying the not logical operation to a value
inverts its “truthiness” (yes, we really use that nonword), and returns
a Boolean value (True or False). The same with if-statements: they
also test the “truthiness” if their expression.

The second is that there’s a convention in Python that the “truthiness”
of an object is normally designed to be false for zero or empty things.
So these are falsey examples:

  • 0, a int zero
  • 0.0, a float zero
  • [], an empty list
  • (), an empty tuple
  • None, the normal placeholder for “no value” (Python does not have a
    “no value”)
  • "", an empty string (str)

Conversely, these test as true:

  • 1, a nonzero int
  • 9, another nonzero int
  • [1,2,3], a nonempty list
  • "abc", a nonempty str

And this is a little reinforced because Booleans (Python’s bool type,
True and False) are in fact a special subclass of int, with 0 for
False and 1 for True.

Also, the expression not n % 2 relies on the operator precedence of
% binding tighter than the operator precedence of not. Now it
happens that arithmetic operators do bind tighter than logic
operators, because that lets us write:

 if 3+5 > 0 and x+y > 9:

and generally have it mean what we intend. But relying on that for an
expression feels… slightly wobbly. You want to get the result of
not(n%2) and not the result of (not n)%2.

So what Rob is doing is:

  • computing the remainder when you divide by 2
  • testing its falsiness

Now, a remainder of 0 does indeed test as falsey, and conversely
nonzero tests as truthy. But that relies on a quirk of the language
specification, not the inherent numeric situation, which should look
like:

 n % 2 == 0

i.e. “is the remainder 0”?

So I recommend that form to you.

Cheers,
Cameron Simpson cs@cskk.id.au

2 Likes

Yes, I agree. To be fair to @Peekay that was in the original code posted; it’s a bad coding habit that I’ve picked up from somewhere; I’ll try to drop it.

1 Like

Dave, in your variation of the code you name the function “myfunc”, but then try to call a non-existent function “list_even”.

That’s why you are getting the error.

You seem to have a bit of confusion as to what name goes with what. In your myfunc function, you name the input argument “x”. But then you try to iterate over the function myfunc:

def myfunc(x):
    list_even = []
    for n in myfunc:  # WRONG! Change to "for n in x:"
        if not n %2:
            list_even.append(n)
    return list_even

numbers = [2,3,4,6,8,101,103,111,120,124]
print(list_even(numbers))  # WRONG! Change to "print(myfunc(numbers))"

We can improve this by choosing better names, that describe what the purpose of the function or variable is:

def get_evens(list_of_numbers):
    list_of_evens = []
    for n in list_of_numbers:
        if n % 2 != 0:
            list_of_evens.append(n)
    return list_of_evens

numbers = [2, 3, 4, 6, 8, 101, 103, 111, 120, 124]
print(get_evens(numbers))

What happens here is that when the interpreter gets to the line numbers = [2, 3, ...] it creates a list of numbers and gives it a name “numbers”.

This is a global variable, because anywhere inside your script (the .py file) can see it – it is global to the entire script.

When you pass the variable to the get_evens function, the interpreter takes the list and gives it a second name, “list_of_numbers”. Unlike the name “numbers”, which is global, “list_of_numbers” is a local variable so it is only visible to code inside the get_evens function.

Being local to the get_evens function, if you try to refer to “list_of_numbers” outside of the get_evens function, you will get an error that the name doesn’t exist.

The reason why the “numbers” list is defined underneath the function is… no particular reason. It is common practice to define your functions at the top of the .py file, and data below them, but it is not compulsary. The only thing that is mandatory is that the data and the function exists when you use them.

# This is okay.

my_name = 'Steve'

def greet(name):
    print("Hello", name)

greet(my_name)

# This is also okay.

def salutations(name):
    print("Greetings and salutations", name)

your_name = 'Dave'
salutations(my_name)

# But this section is NOT OKAY and will fail.

say_goodnight(her_name)
# It fails because the function and the variable don't exist yet!
# You will get a NameError exception.

her_name = 'Gracie'

def say_goodnight(name):
    print("Say goodnight,", name)
    print("Goodnight", name + "!")

Hope this helps explain why and when the interpreter will see a name versus complaining it doesn’t exist.

Thanks you guys , this has VERY educational.
Steven… the procedure you ammended works by producing the correct output but is still creating an error. Keep in mind, I am in an education software practice exercise so the error may not actually be a Python error but something related to the course. see below, do you recognize this error?
image

“myfunc takes 1 positional argument but 5 were given”

def myfunc(x):
    list_even = []
    for n in x:  
        if n %2 == 0:
            list_even.append(n)
    return list_even

numbers = [2,3,4,6,8,101,103,111,120,124]
print(myfunc(numbers))  

Yes, it is a Python’s error message used with the TypeError exception. It says that the function myfunc() was defined to accept a single argument but it was called with five arguments instead. Here is a short demonstration:

>>> def myfunc(x):
...     return x
...
>>> myfunc(1, 2, 3, 4, 5)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: myfunc() takes 1 positional argument but 5 were given

I guess you might not be following the assignment exactly (a guessed hint: Maybe it is not your code which should call myfunc()). Try to re-read it carefully and if you are still out of ideas what could be wrong, show us the exact text of the assignment.

This is the exact problem verbatim. And yes, now getting more confused

" Define a function called myfunc that takes in an arbitrary number of arguments, and returns a list containing only those arguments that are even.

Remember, don’t run the function, simply provide the definition.

To give an idea what the function would look like when tested:

  1. myfunc(5,6,7,8)
  2. Output: [6, 8]

Added note: this exercise requires that the function return a list. Print statements will not work here."

Ok so I’m getting close !

def myfunc(*args):
    args=[3, 4, 6, 7, 8, 10, 11, 102, 2002, 4001, 5004]
    number_list = args
    even_list=[]
    for x in number_list:  
        if x %2 == 0:
            even_list.append(x)
    print(even_list)

you’ll notice I get the correct output, but still creating an error. Have you seen this error before?

image

Ok, now you follow these two instructions which were not followed before:

  • Define a function … that takes in an arbitrary number of arguments
  • Remember, don’t run the function, simply provide the definition.

I see that you are ignoring the args argument. As you show the function it does not matter how you call it. It will always return the same list.

The error message seems to compare the expected output to the actual output of your function (which is None). I am wondering does the message show the testing input?


I noticed this later (because I did not expect that): Now you are not following these instructions:

  • Define a function called myfunc that … returns a list containing only those arguments that are even.
  • Added note: this exercise requires that the function return a list. Print statements will not work here.

The *args should satisfy the arbitrary number of values requirement. I just uncertain how to produce the same output using “return” I’ve tried it, it keeps telling me “undefined”

def myfunc(numlist):
    numlist=([0,1,4,8,10,1000,4002,5003,1000000,7,9,12])
    list(filter(lambda num:num%2 ==0,numlist))

this is a variation I’m toying with. It’s actually one of the same procedures the instructor uses. This is producing an error as well relating to the numberb of variables it’s expecting. Any ideas ?

Let’s go back to this code of yours:

More concrete hints:

  • args=[3, 4, 6, 7, 8, 10, 11, 102, 2002, 4001, 5004] - What is the purpose of this statement? By assigning a value to a variable (args) you throw away the original value. In effect you are ignoring the argument value given to the function. You need to work with the argument otherwise it does not make sense.
  • print(even_list) - “Print statements will not work here.
  • The function does not return the result. You need to use the statement return to do that. You already did that in your earlier code. Why abandoning it here?

I recommend you reading a little bit about functions. I think the information you need is here:

By Dave via Discussions on Python.org at 16Sep2022 16:56:

Please use 3 backticks. The above are tildes (~).

def myfunc(numlist):
numlist=([0,1,4,8,10,1000,4002,5003,1000000,7,9,12])
list(filter(lambda num:num%2 ==0,numlist))

this is a variation I’m toying with. It’s actually one of the same
procedures the instructor uses. This is producing an error as well
relating to the numberb of variables it’s expecting. Any ideas ?

This function expects exactly one argument (numlist). To accept an
arbitrary number of arguments you want a definition like this:

 def myfunc(*numbers):

The asterisk (*) says to collect all positional arguments and save
them in the variable numbers. Number isn’t a list, it is a tuple,
but that doesn’t matter for your function - you can still iterate over
it to pick out the even numbers.

Example use of the asterisk in the parameters:

 >>> def f(*a):
 ...   print(type(a), a)
 ...
 >>>
 >>>
 >>> f(1,2,3)
 <class 'tuple'> (1, 2, 3)

so the variable a is a tuple of 3 values.

Cheers,
Cameron Simpson cs@cskk.id.au

Thank you to all who took the time to comment and showed patience with a new Python developer. The below code works !

def myfunc(*args):
    even_list = []
    for x in list(args):
        if x%2==0:
            even_list.append(x)
        else:
            pass
        
    return even_list

image

1 Like