Python basic question which i really cant understand the logic [duplicate] - python

This question already has answers here:
Understanding this Python code from 2014's new year challenge
(6 answers)
Generator expression evaluation with several ... for ... in ... parts
(2 answers)
Explain python list comprehension technique
(2 answers)
Closed 1 year ago.
def sum_five(l):
return sum(num for num in l if num > 5)
#desired outcome:
#sum_five([1, 5, 20, 30, 4, 9, 18]) ➞ 77
#sum_five([1, 2, 3, 4]) ➞ 0
#sum_five([10, 12, 28, 47, 55, 100]) ➞ 252
gotten this as a solution. The question is to loop through a list and sum up those that are less than 5. This is the cleanest and shortest answer which i really loved to learn. Can anyone explain in very simple English to me what does the num for num in l if num > 5 really means?
And give me more examples to understand that logic so i can next time apply it? PS: i can do the outcome using for loop and if statement already, i just want to learn how to use this one liner. Thanks.

This is known as Generator Expression which gives you another list which means like this:
FOR any element which we call it num, in the list which we call it l, if this element(num) is greater than 5, take it and put it in result list.
For example for [1,2,3,4] there is no number greater than 5, so the result is [] which has the summation equal to zero.
Another example is [1,5,20,30,4,9,18] which has the result equal to [20,30,9,18] which has the summation equal to 20+30+9+18 = 77

The list comprehension -- any list comprehension -- can be written as a for loop remembering that it returns a list (meaning you don't have to write the part that assigns the result to a list which in this case I've called out). That's a good thing because that list you are taking the sum of and returning that result instead.
out = []
def sum_five(l):
for num in l:
if num > 5:
out.append(num)
else:
continue
return sum(out)
The general form a list comprehension is worth going into more. But I'm going to strip out some of the code to this for clarity
for num in l:
if num > 5:
num
Goes to this:
for num in l if num > 5:
num
And then to this:
num for num in l if num > 5:
We don't need that colon at the end and the whole thing gets put in braces because that's what specifies a list is getting returned. That leaves us with:
[num for num in l if num > 5]
You then take the sum of that list:
sum([num for num in l if num > 5])
You'll notice the formatting is a bit different than for the loop. If it was just a long no one would use it.

Related

Problems getting code to repeat/work for each value in list [duplicate]

This question already has answers here:
Why do I get an IndexError (or TypeError, or just wrong results) from "ar[i]" inside "for i in ar"?
(4 answers)
Apply function to each element of a list
(4 answers)
Accessing the index in 'for' loops
(26 answers)
Closed 5 months ago.
I'm having problems getting my code to work appropriately for each value in a list.
The purpose of the code is to create a function which has an input argument numList, a list. The function replaces every odd number in the list with 0 and return the new list.
def onlyEvens(numList):
for onlyEvens in numList:
if onlyEvens % 2 != 0:
numList[onlyEvens] = 0
return numList
print(onlyEvens([ 1, 5, 2, 3, 4 ]))
It outputs [1, 0, 2, 3, 4] however the desired output is [0, 0, 2, 0, 4]. Where did I go wrong?
Solution
You can solve your issue as follows:
def onlyEvens(numList):
for i in range(len(numList)):
if onlyEvens % 2 != 0:
numList[i] = 0
return numList
Explanation
The problem lies within your 3rd line of code: numList[onlyEvens]. onlyEvens is an element in the list and not an index. What does that mean? See the examples below.
Example 1
Code
list = ['a', 'b', 'c']
for letter in list:
print(letter)
Output
'a'
'b'
'c'
Example 2
Code
list = ['a', 'b', 'c']
for i in range(len(list)): # Repeat it as many times as the length of list.
print(i)
Output
0
1
2
You're using onlyEvens as an index to numList, instead of using the actual index of onlyEvens. You're also returning immediately instead of after going through the whole list, because of the indentation of your return. One solution for getting the index of each onlyEvens is to use enumerate:
def onlyEvens(numList):
for i, onlyEvens in enumerate(numList):
if onlyEvens % 2 != 0:
numList[i] = 0
return numList
print(onlyEvens([ 1, 5, 2, 3, 4 ]))
Output:
[0, 0, 2, 0, 4]
For more info on enumerate: https://docs.python.org/3/library/functions.html#enumerate
Using onlyEvens as the name of both a function and a variable in that function is confusing and error-prone. I'd suggest changing that. Also notice that you return inside your loop so you'll return after processing the first element. So move that outside your loop.
Let's also add a print statement to help debug. So let's say your code now looks like:
def onlyEvens(numList):
for num in numList:
if num % 2 != 0:
print('Found a odd number:', num)
numList[num] = 0
return numList
If you run that you'd see that it first processes 1, the first number in the list and, since that's odd, you'd see Found an odd number: 1. Now look at the next line: you use that as an index into numList But the index of 1 in that list isn't 1 - it's 0 so you end up replacing the wrong element. Try changing your loop to something like:
for i, num in enumerate(numList):
and I think you'll be able to solve it from there.

in Python, I get a wrong total, i only get the total of the positive numbers that are located before the negative ones [duplicate]

This question already has answers here:
Sum list values within a given range using while loop
(2 answers)
Closed 2 years ago.
i wrote this code in python:
list=[3,5,7,6,-9,5,4]
i=0
total=0
while i<len(list) and list[i] > 0:
total+=list[i]
i+=1
print(total)
and instead of getting the total of all positive numbers i only get the total of numbers that are located before the negative one, i'm not sure what i'm doing wrong, this is just my fourth code in python i'd like some help^^
That is because you have the condition that the loop ends if you encounter a negative number. You can first remove that condition from the loop.
while i<len(list):
Next, you only want to add non-negative numbers so, use a conditional statement in the loop with the condition that you want.
if list[i] > 0:
Try to understand the working of while loop. It works as long as i < len(list and list[i] > 0. When it reaches the value -9, the while loop's second condition gets false and it terminates. Hence no sum is calculated after first negative integer is encountered.
To solve this, do
lis = [3, 5, 7, 6, -9, 5, 4]
sum = 0
for i in lis:
if i > 0:
sum += i
For your while loop code, use
lis = [3, 5, 7, 6, -9, 5, 4]
i = 0
sum = 0
while i < len(lis):
if lis[i] > 0:
sum += lis[i]
i = i + 1
Also, although you can use a variable name as list, it is advised not to do so in Python as list is also a keyword.
Do not use a while loop in this case. Iteration over items in a container is easier in Python with a for loop. Plus the logic is wrong and exits the while loop early when it fails the and list[i] > 0 condition.
lst = [3,5,7,6,-9,5,4]
total = 0
for item in lst:
if item > 0:
total += item
print(total)
Also, don't use list as a variable name. That replaces the built-in list type and is called "shadowing".
You can also use a list comprehension and simplify the code even more:
lst = [3,5,7,6,-9,5,4]
total = sum([item for item in lst if item > 0])
print(total)

Why is my function returning these values? [duplicate]

This question already has answers here:
How to remove items from a list while iterating?
(25 answers)
Closed 3 years ago.
Hey guys/girls total noob over here, but I can't for the life of me figure out why this function isn't sorting out all the values below 40. I'm really surprised because it's such a basic task, even for me but I've been staring at it for a while now and can't figure it out.
def sort(list):
list.sort()
for num in list:
if num < 40:
list.remove(num)
return list
print (sort([-31, 0, 5, 76, 12, 32, 4, 88]))
Output : [0, 5, 32, 76, 88]
Your function is sorting out the values alright.
The problems is that you're messing with the list iterator when you remove items during the iteration. You cannot remove elements from a list while looping through its elements.
What happens is that when you remove an element you don't reset the iterator and, behind the scenes, it uses an index to iterate, so when you remove the item you shift the next item one index back and tell loop moves forward, skipping a few items.
[-31,0,5,76,12,32,4,88]
# first iteration: i = 0, removes -31
[0,5,76,12,32,4,88]
# second iteration: i = 1, removes 5
See what happened?
An alternative is to use a while:
while len(list) > 0 and list[0] < 40:
list.pop(0)
Another alternative is to, since you sorted the list, find the index for the greater number below 40 and then remove all elements before it in a single blow:
max_b40_index = None
for (e, e_index) in enumerate(list):
if e >= 40: break
max_b40_index = e_index
return list[:max_b40_index+1]
The list[:n] code returns a subset from index n to the end of the list.
Oh, be sure to check that max_b40_index isn't none. You might have a list without any numbers below 40.

list compression weird behavior [duplicate]

This question already has answers here:
List comprehension with if statement
(5 answers)
Closed 3 years ago.
I have question about list comprehension. If I want to output the odd squared numbers and put the condition in the output part (I know how to put condition in the loop part to get the desired result)
[num**2 if num % 2==0 for num in range(10)]
returned an error code. Why Python doesn't like it?
By adding else, the following returns zeros
[num**2 if num % 2==0 else 0 for num in range(10)]
so I tried to remove zeros on top of this
[num**2 if num % 2==0 else 0 for num in range(10)].remove(0)
and python returned empty, why?
[num**2 if num % 2==0 for num in range(10)] returned an error code. Why Python doesn't like it?
You have the list comprehension syntax backwards. The for comes first, then the if.
[num**2 for num in range(10) if num % 2 == 0]
Alternatively, use range’s step parameter:
[num**2 for num in range(0, 10, 2)]
The list comprehension is out of order.
A list comprehension consists of brackets containing an expression
followed by a for clause, then zero or more for or if clauses. -- Python, Data Structures Documentation, List Comprehensions
Change your first one to:
[num**2 for num in range(10) if num % 2 == 0]
output:
[0, 4, 16, 36, 64]

How to add values into an empty list from a for loop in python?

The given python code is supposed to accept a number and make a list containing
all odd numbers between 0 and that number
n = int(input('Enter number : '))
i = 0
series = []
while (i <= n):
if (i % 2 != 0):
series += [i]
print('The list of odd numbers :\n')
for num in series:
print(num)
So, when dealing with lists or arrays, it's very important to understand the difference between referring to an element of the array and the array itself.
In your current code, series refers to the list. When you attempt to perform series + [i], you are trying to add [i] to the reference to the list. Now, the [] notation is used to access elements in a list, but not place them. Additionally, the notation would be series[i] to access the ith element, but this still wouldn't add your new element.
One of the most critical parts of learning to code is learning exactly what to google. In this case, the terminology you want is "append", which is actually a built in method for lists which can be used as follows:
series.append(i)
Good luck with your learning!
Do a list-comprehension taking values out of range based on condition:
n = int(input('Enter number : '))
print([x for x in range(n) if x % 2])
Sample run:
Enter number : 10
[1, 3, 5, 7, 9]

Categories