Related
The prompt is:
Using PyCharm, under lab8, under Directory exercise, create a Python file called
more_loops.py. Write a function, nbrs_greater that accepts 2 integer lists as parameters,
and returns a list of integers that indicates how many integers in the second list are greater than each integer in the first list. For example: nbrs_greater([3, 4, 1, 2, 7], [10, 1, 4, 2, 5, 3]) returns [3, 2, 5, 4, 1]
And my code is working sometimes, but when I enter:
nbrs_greater([20, 5, 1, 6], [1, 4, 8, 12, 16])
It won't continue past 6 and returns [0, 3, 4] instead of [0, 3, 4, 3] because there are three values for which 6 is greater than in list 2.
Here is my original code--------
def nbrs_greater(list_1, list_2):
final_list = []
list_count = []
list_greater = []
number_of_greater = 0
for i in list_1:
for j in list_2:
if i < j:
list_greater.append(i)
number_of_greater += 1
if i > max(list_2):
list_count.append(0)
for k in list_greater:
count_list_var = list_greater.count(k)
list_count.append(count_list_var)
for h in list_count:
if h not in final_list:
final_list.append(h)
if len(final_list) == 0:
final_list.append(0)
return final_list
print(nbrs_greater([20, 5, 1, 6], [1, 4, 8, 12, 16]))
You're making this much more complicated than it needs to be. You don't need a list of each number that's greater in order to get the count. You can use the sum() function to get a count.
def nbrs_greater(list_1, list_2):
final_list = []
for i in list_1:
greater_count = sum(j > i for j in list_2)
final_list.append(greater_count)
return final_list
At here if h not in final_list: you mean final_list has not same num,so it won't apear two '3'.The different count numbers can be ok.
I have a list where I would like to +1 to all the values after n in a loop, where n is a row index. I want to repeat this multiple times to achieve the following:
original_list = [1,2,3,4,5,6,7]
multiples = [3,6] #i.e. index 2 & 5
for i in multiples:
Do Something to +1...
final_list = [1,2,4,5,6,8,9]
Slicing lists within loops doesn't seem that clear to me, does anyone know how to think about solving this?
original_list = np.array([1,2,3,4,5,6,7])
multiples = np.array([3,6])
cs = np.zeros_like(original_list)
multiples = np.array(multiples) - 1 # since you are not using 0-index
cs[multiples] = 1
original_list + cs.cumsum()
Output:
array([1, 2, 4, 5, 6, 8, 9])
You don't need to do any fancy list slicing actually. You can accomplish this with an additional index, j, that goes from i + 1 (after n) to the len of the original_list.
original_list = [1,2,3,4,5,6,7]
multiples = [3,6]
for i in multiples:
for j in range(i+1, len(original_list)): # i+1 if you count from 0, i-1 if you count from 1
original_list[j] += 1
>>> original_list
[1, 2, 3, 4, 6, 7, 8] or [1, 2, 4, 5, 6, 8, 9] (with i-1)
If you are counting from 1 (instead of 0), then change i+1 to i-1 and your original_list becomes [1, 2, 4, 5, 6, 8, 9].
original_list = np.array([1,2,3,4,5,6,7])
final_list = np.array(original_list, copy=True)
multiples = [3,6]
for i in multiples:
final_list[i-1:] = final_list[i-1:] + 1
When wanting the following output
final_list = [1,2,4,5,6,8,9]
The case is if I want to reverse select a python list to n like:
n = 3
l = [1,2,3,4,5,6]
s = l[5:n:-1] # s is [6, 5]
OK, it works, but how can I set n's value to select the whole list?
let's see this example, what I expect the first line is [5, 4, 3, 2, 1]
[40]: for i in range(-1, 5):
...: print(l[4:i:-1])
...:
[]
[5, 4, 3, 2]
[5, 4, 3]
[5, 4]
[5]
[]
if the upper bound n set to 0, the result will lost 0. but if n is -1, the result is empty because -1 means "the last one".
The only way I can do is:
if n < 0:
s = l[5::-1]
else:
s = l[5:n:-1]
a bit confusing.
To fully reverse the list by slicing:
l = [1,2,3,4,5,6]
print(l[::-1])
#[6, 5, 4, 3, 2, 1]
If you want to be able to partially or fully reverse the list based on the value of n, you can do it like this:
l = [1,2,3,4,5,6]
def custom_reverse(l,n):
return [l[i] for i in range(len(l)-1,n,-1)]
print(custom_reverse(l,3)) #[6, 5]
print(custom_reverse(l,-1)) #[6, 5, 4, 3, 2, 1]
Hopefully this is what you mean.
print(l[n+1::-1])
i am confuse at some point in my python code, i am trying to build a program which return the cumulative sum, that is where is the ith element is the sun of first i+1 elements from the origional list. So cunmulative sum of [1,2,3] is [1,3,6], i tried to build program and its working but for first element its adding last element as previous element, that made me think that is structure of python list something circle??
h=[]
a=[1,2,3,4,5,6]
for i in range(len(a)):
d=a[i]+(a[i-1]+1)
h.append(d)
print(h)
Result
[8, 4, 6, 8, 10, 12]
The culprit is with a[i - 1] in the 0th iteration:
d = a[i] + (a[i - 1] + 1)
What actually happens is that i - 1 is reduced to -1, and in python, a[-1] refers to the last element in the list:
In [568]: l = [1, 2, 3, 4]
In [569]: l[-1]
Out[569]: 4
The solution here would be to start your loop from 1. Alternatively, you would consider the use of a temp variable, as mentioned here:
a = [1, 2, 3, 4, 5, 6]
h = []
cumsum = 0
for i in a:
cumsum += i
h.append(cumsum)
print(h)
[1, 3, 6, 10, 15, 21]
As a side, if you're using numpy, this is as simple as a single function call with np.cumsum:
h = np.cumsum([1, 2, 3, 4, 5, 6])
print(h)
array([ 1, 3, 6, 10, 15, 21])
Just wanted to add that you could use itertools.accumulate to accumulate the results of a binary operation, in this case, addition. Note, itertools.accumulate actually defaults to addition:
>>> a = [1, 2, 3, 4, 5, 6]
>>> a = [1, 2, 3, 4, 5, 6]
>>> import itertools
>>> list(itertools.accumulate(a))
[1, 3, 6, 10, 15, 21]
But you could pass it a binary operation and do a cumulative product, for example:
>>> list(itertools.accumulate(a ,lambda x, y: x*y))
Better yet, harness the power of the operator module:
>>> list(itertools.accumulate(a, operator.add)) #cumulative sum
[1, 3, 6, 10, 15, 21]
>>> list(itertools.accumulate(a, operator.mul)) #cumulative product
[1, 2, 6, 24, 120, 720]
>>> list(itertools.accumulate(a, operator.truediv)) #cumulative quotient
[1, 0.5, 0.16666666666666666, 0.041666666666666664, 0.008333333333333333, 0.001388888888888889]
>>> list(itertools.accumulate(a, operator.floordiv)) #cumulative floor div
[1, 0, 0, 0, 0, 0]
Yes - it is a little like that. In python a[-1] gives you the last element of the list.
If you seed the result with the first item your code and start from 1 rather than 0 can be made to work:
a=[1,2,3,4,5,6]
h=[a[0]]
for i in range(1,len(a)):
d=a[i]+(h[i-1])
h.append(d)
print(h)
Lists are not circular, but the can be referenced from either the beginning or the end. You can use [-1] to reference from the end of the list.
But, if you try to reference the 20th element of a list that only has 10 elements, you will receive an error. If lists were circular, it would refer to the 10th element, but it does not.
What you want is this, I believe:
a = [1,2,3,4,5,6]
h = []
index = 0
for i in range(len(a) - 1):
first = a[index]
second = a[index + 1]
summation = first + second
h.append(summation)
index += 1
print(h)
Trying to write a function that take the sum of each list and return individual values in a new single list.
E.g
[[2, 7, 6], [9, 5, 1], [4, 3, 8]]
becomes
[15, 15, 15]
What I have so far:
def row_sums(square):
total_list = []
total = 0
for i in square:
for j in i:
total += j
total_list.append(total)
return total_list
But this just accumulates each list onto each other resulting in:
[15, 30, 45]
I'm not sure how to keep the sums for each list separate here. The SUM function is not allowed here as it's an exercise on nested loops.
Thanks.
You need to reset your total counter before starting each inside for.
Also, you don't need to declare it outside, because you will use it only inside.
def row_sums(square):
total_list = []
for i in square:
total = 0
for j in i:
total += j
total_list.append(total)
return total_list
The error is you do not re-initialize the total variable after each loop. Instead, initialize sum = 0 inside he first for-loop like so:
def row_sums(square):
total_list = []
for i in square:
total = 0
for j in i:
total += j
total_list.append(total)
return total_list
Just for fun:
>>> list = [[2, 7, 6], [9, 5, 1], [4, 3, 8]]
>>> import functools
>>> [functools.reduce(lambda x, y: x + y, sublist, 0) for sublist in list]
[15, 15, 15]
I did't use sum :)
You can read more about functools.reduce here.
Edit: As Sevanteri pointed out in the comment, you can also use [functools.reduce(int.__add__, sublist, 0) for sublist in list]
(if you really want to drive your teacher mad!)
You need to zero your total for each list.
def row_sums(square):
total_list = []
total = 0
for i in square:
for j in i:
total += j
total_list.append(total)
total = 0
return total_list
To be different, flatten the lists and using a generator (assumes sublists are the same length):
def _notsum2(lists):
per_yield = len(lists)
total = 0
for ind, next in enumerate(val for sublist in lists for val in sublist):
if ind % per_yield == 0 and ind:
yield total
total = 0
total += next
yield total
if __name__ == '__main__':
li = [[2, 7, 6], [9, 5, 1], [4, 3, 8]]
print [g for g in _notsum2(li)]
You can also do it using map and list comprehension as:
l=[[2, 7, 6], [9, 5, 1], [4, 3, 8]]
a,b,c=[x for x in l]
map(lambda x,y,z:x+y+z, a,b,c)
[sum(i) for i in zip(*[[2, 7, 6], [9, 5, 1], [4, 3, 8]])]
bultin zip func is what you exactly needed