Finding the sum of a nested list of ints - python

import math
lists = [1,[2,3],4]
total = 0
for i in range(len(lists)):
total += sum(i)
print(total)
I want it to print,
>>>10
But throws an error.
I would like it to get it to add all numbers, including the ones within the nested if.

In your program, for i in range(len(lists)) - evaluates to 3 as the lists object has 3 element. and in the loop total += sum(i) it would try to do a int + list operation, which results in an error. Hence you need to check for the type and then add the individual elements.
def list_sum(L):
total = 0
for i in L:
if isinstance(i, list):
total += list_sum(i)
else:
total += i
return total
This is #pavelanossov 's comment - does the same thing, in a more elegant way
sum(sum(i) if isinstance(i, list) else i for i in L)

You can use flatten function in the compiler.ast module to flatten the list. Then simply sum up all the elements.
>>> lists = [1,[2,3],4]
>>> from compiler.ast import flatten
>>> sum(flatten(lists))
10
EDIT: Only works with Python 2.x

numpy.hstack() function is used to stack the sequence of input arrays horizontally (i.e. column wise) to make a single array which is what we require in OP example
import numpy as np
list1 = [1,[2,3],4]
M = np.hstack(list1)
print(np.sum(M))
gives
10
[Program finished]

Related

Finding a common number from the list and placing it in another list

I have two lists that are formed through a function called factors which returns the prime factors of a number. In my task I have to return the common numbers in both the lists to a new list.
def factors(n):
i = 2
prime_factors = []
while i*i <= n:
if n%i == 0:
prime_factors=prime_factors + [i]
n //= i
else:
i += 1
if n>1:
prime_factors=prime_factors + [n]
return prime_factors
>>>factors(4)
>>>[2,2]
>>>factors(14)
>>>[2,7]
I have to find the common number and return it in a new list. I tried my code below and it gave me result list as [2,2], whereas it should only be [2]
lst=[]
for element in factors(4):
if element in factors(14):
lst=lst+[element]
This code gives me the result as [2,2]. Kindly guide me as to how I can get only [2]. Also I am NOT allowed to use methods like set, intersection, or zip or stuff from math library. another example:
lst1=[2,2,3,3,4,5,6]
lst2=[2,2,3,4,4,7,8]
common_lst=[2,2,3,4]
(Note: this was for an earlier version of the question, before they vandalized the question to say the math "library" isn't allowed and that they want to keep common duplicates. Oh well, gcd is a short one-liner we could write ourselves instead.)
>>> from math import gcd
>>> factors(gcd(4, 14))
[2]
or
>>> [*{*factors(4)} & {*factors(14)}]
[2]
(They're not quite equivalent, they solve two different interpretations of the ambiguous question. I actually suspect the first one is the desired one, as otherwise the OP might not have made the factors function produce duplicate factors in the first place.)
The Counter method from the collections library would come in handy here. Counter takes in a list and returns a dictionary of the number of 'counts' of each value in that list.
from collections import Counter
f4 = factors(4)
f14 = factors(14)
c4 = Counter(f4)
c14 = Counter(f14)
inter = c4 & c14
lst = list(inter.elements())
inter represents the intersection between the two dictionaries. list(inter.elements()) simply retrieves the elements of the dictionary as a combination of the key and value and converts the result to a list.
If i understand the question correctly, the only way to solve it is to delete the common numbers as they are found. (To do this i have iterated through the lists backwords to prevent Index errors)
lst = []
fctrs_1 = factors(4)
fctrs_2 = factors(14)
for a in range(len(fctrs_1)-1, -1, -1):
for b in range(len(fctrs_2)-1, -1, -1):
if fctrs_1[a] == fctrs_2[b]:
lst.append(fctrs_1[a])
del fctrs_1[a]
del fctrs_2[b]
break # Break to prevent errors
print(lst)# Output: [2]

A function that calculates the average of a list and returns the elements that are greater than the mathematical average of the entire list

I'm trying to make a function that would calculate the average of a given list then returns all the elements within that list which are greater than the mathematical average of that list. Example:
if the given list is [1,2,3,4,5,6], the average would be 3.5. So the function should print out the numbers (4,5,6).
I've gotten as far as adding all the numbers up within the list but no matter what I do, I can't figure out how to get the average or get it to print out the numbers that are greater than the mathematical average.
This is what i have so far to add all the elements of any given list:
def accum2(seq):
total = 0
for x in seq:
total += x
return total
print (accum2([1,2,3,4,5,6]))
The expected result of print (accum2([1,2,3,4,5,6])) should be (4,5,6) but so far I just get an answer where it just adds up all the number in the given list.
Any help is greatly appreciated and thank you in advance.
The simplest way to get the average value of a list of numeric values is to use the methods:
average = sum(seq) / len(seq)
From there just use a conditional statement (you might have to sort the list first, if it is unsorted). From there you should be able to build a new list using the built in list methods.
heres some simple code which should work.
I have added comments.
originallist = [1,2,3,4,5,6] #This is your original list
outputlist = [] #This is the list which you can add correct values to
x = sum(originallist) / len(originallist) #This effectively finds you the average
for item in originallist: #Checks which items are greater than average
if item > x:
outputlist.append(item) #If greater, add to the final list
print(outputlist)
There are many correct ways to do this, one of which is shown below (Python 3).
lst = [1,2,3,4,5,6]
avg = sum(lst)/len(lst)
res = list(filter(lambda x: x > avg, lst))
print(res)
will produce
[4,5,6].
I prefer this approach because it's less verbose than loops and also can be more easily translated to a framework like Pandas or an eventual parallel implementation if such a need arises in the future (e.g., using Spark).
This is the extended version of your work:
def accum2(seq):
total = 0
for x in seq:
total += x
L=[]
for x in seq:
if x>total/len(seq):
L.append(x)
return L
print (accum2([1,2,3,4,5,6]))
But you could simply the previous one in this code:
def accum2(seq):
return [x for x in seq if x>(sum(y for y in seq)/len(seq))]
print (accum2([1,2,3,4,5,6]))

Find a deleted number from a list

Considering two lists (a sequence of numbers from 1 to N (arr) and the same sequence mixed but missing one number (mixed_arr)). The goal is to find the number that was deleted.
Example:
arr = [1,2,3,4,5]
mixed_arr = [3,4,1,5]
The output should be 2.
Return 0 if no number was deleted and if there is no difference
If no number was deleted from the array and no difference with it, the function has to return 0. Note that N may be 1 or less (in the latter case, the first array will be []).
Testcases:
arr = [1,2,3,4,5,6,7,8,9]
mixed_arr = [1,9,7,4,6,2,3,8]
output = 5
arr = [1,2,3,4,5,6,7,8,9]
mixed_arr = [5,7,6,9,4,8,1,2,3]
output = 0
Here's my code:
def find_deleted_number(arr, mixed_arr):
arr.sort()
mixed_arr.sort()
for x in range(arr):
for y in range(mixed_arr):
if arr[x] != mixed_arr[y]:
return arr[x]
elif arr[x] == mixed_arr[y]:
return 0
The error I get is:
Traceback:
in <module>
in find_deleted_number
TypeError: 'list' object cannot be interpreted as an integer
Why not to use set?
>>> arr = [1,2,3,4,5,6,7,8,9]
>>> mixed_arr = [1,9,7,4,6,2,3,8]
>>> list(set(arr) - set(mixed_arr))
[5]
This general solution will handle arrays with no constraints on integers, or on the size of lists (or the size of the difference).
Edit. In your (very) specific case with positive integers, and only one missing in the other array, it's much more efficient to use the solution from comments below:
>>> abs(sum(arr) - sum(mixed_arr))
5
You could simply use symmetric_difference(), a member of set:
set(arr).symmetric_difference(mixed_arr)
See also sets.
Please note, as pointed out by DeepSpace in the comments, if it is guaranteed that both lists contain integers from 1 to N, with the exception of one missing in one of those lists, the much more efficient solution is to compute the absolute value of the difference of the sum of both lists:
abs(sum(arr) - sum(mixed_arr))
The error you're getting:
You're getting the error because of this line:
for x in range(arr): # arr is a list, not an int
You surely intended to pass the length of the array:
for x in range(len(arr)):
The same goes for the inner loop.
Your problem is that you are trying to pass an list object to the range() function. But since range() only accepts integers, Python complains. You are also making the same mistake with mixed_arr.
But there are easier ways to accomplish this. In this case, you can use set()s to find the difference between two lists:
>>> set([1,2,3,4,5]) - set([3,4,1,5])
{2}
>>>
Or this could be done using a simple list comprehension:
>>> arr = [1,2,3,4,5]
>>> mixed_arr = [3,4,1,5]
>>>
>>> [el for el in arr if el not in mixed_arr]
[2]
>>>

Replace for with list comprehension

In this script I have used both list comprehension and for. I need to replace for loop with comprehension and add this solve inside list comprehension.
How can add
for i in k:
count_list.append(l.count(i))
inside this block
pairs = [int(pair/2) for pair in count_list if int(pair/2) != 0]
My code:
def sockMerchant(ar):
l = ar
k = set(l)
count_list = []
for i in k:
count_list.append(l.count(i))
pairs = [int(pair/2) for pair in count_list if int(pair/2) != 0]
return sum(pairs)
n = int(input().strip())
ar = list(map(int, input().strip().split(' ')))
result = sockMerchant(ar)
print(result)
You should not be using a list comprehension at all, nor the for loop you have now. The loop is inefficient; by using list.count() you are traversing the whole list l for every unique value, creating a O(N^2) loop.
Use a collections.Counter() object instead and count in O(N) time:
from collections import Counter
def sockMerchant(ar):
counts = Counter(ar)
return sum(count//2 for count in counts.values())
or even
def sockMerchant(ar):
return sum(count//2 for count in Counter(ar).values())
if you insist on a single line.
Note that sum() doesn't mind a few 0 values here and there, so I removed the if test for single 'socks'. Also, I used the // floor division operator rather than turning the floating point result of dividing by 2 back into an integer.

Python sorting arrays to get two digit values

I have an array A = [1 - 100] and I need to find the sum of all the two digit values in this array. How would I approach this? I have tried :
def solution(A):
A =array[0-100])
while A > 9 & A < 99
total = sum(A)
print "%s" % total
)
Is there a function that given an array consisting of N integers returns the sum of all two digit numbers i.e A = [1,1000,80, -91] the function should return -11(as the two are 80 and -91). not a range, multiple array
You can use a list comprehension and check if the length of the string-format is equal to 2, like so:
sum([x if len(str(x))==2 else 0 for x in xrange(1,101)])
Use the keyword and rather than the bitwise &.
Edit: a fuller answer, as that's not the only thing wrong:
def solution():
A = range(101)
total = sum([a for a in A if 9 < a <= 99])
print total
This uses list comprehension and chained inequalities, so is pretty 'pythonic'.
There is tons of errors in your code, please next time before posting,spend some time try to figure it out yourself and be sure that your code at lest doesn't contain any obvious syntax error.
By array, I assume you're talking about a list. And change it to range(101) for every number from 0 to 100
def solution(A):
return sum([x for x in range(A) if len(str(abs(x))) == 2])
print(solution(101))
As a side note, use and instead of & since that's a bitwise-or sign.
Here are a couple of ways to go about the problem, the first is most similar to the approach you appear to be trying:
def solution1(array):
total = 0
for a in array:
if 9 < a < 100:
total += a
return total
print(solution1(range(101)))
And here's a more compact solution using a comprehension (actually, a generator expression):
def solution2(array):
return sum(a for a in array if 9 < a < 100)
print(solution2(range(101)))
Note that in your original you're confusing loops and conditionals.

Categories

Resources