Lists with multiplication and addition Python - list

So I have a list that has numbers like [1,2,3,4,5]. What I need the code to be able to multiply and add the numbers so it would look like 1*5 + 2*4 + 3*3 + 4*2 + 5*1. Although these numbers can change based on user input, so it can also look like [1,2,3,4] (1*4+2*3+3*2+4*1)
Also, I'm only allowed to use the operations of the length of list, list accessor, create an empty list, List append.

If you want the result to be stored in a variable, you could do this:
y=[1,2,3,4,5]
s=len(y)
x=0 #initialize result to 0
for i in range(s):
x = x + (y[i]*y[s-1-i])
#y[s-1-i] is the the element to be multiplied with y[i]
print(x)

x=[1,2,3,4,5]
total_sum=sum([a*b for a,b in zip(x,x[::-1])])
Note: x[::-1] reverses the list

Related

Finding the sum of all elements of a list in list which has characters in 1 line

ab = [ ['5','6','7','8','9','10'],['1','2','3'],['3','4','5']]
print sum([sum(int(x) for x in y for y in ab])])
I have to find the sum of all elements in ab with a single print statement. I'm trying to convert each element of each of the lists to int and creating a list which has sum of each individual list.
I get a syntax error and not sure how to do it.
You are defining the for loop for x (the inner loop) before the for loop for y (the outer loop). That is why it is not working. What you need is print sum(int(x) for y in ab for x in y)
Also it might be better to use a generator here because you are not reusing the list, since it is more efficient.

[Leetcode]448. Find All Numbers Disappeared in an Array

problem link from leetcode
I came up with two solutions wrote in Python but did not pass and do not know why.
Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array),
some elements appear twice and others appear once.
Find all the elements of [1, n] inclusive that do not appear in this
array.
Here is my first solution:
class Solution(object):
def findDisappearedNumbers(self, nums):
nums=sorted(list(set(nums)))
for x in range(1, nums[-1] + 1):
if x in nums:
nums.remove(x)
else:
nums.append(x)
return nums
the result is " Runtime Error Message: Line 4: IndexError: list index out of range". But I did not get it.
The second solution:
return [x for x in range(1, len(nums) + 1) if x not in nums]
The result is "Time Limit Exceeded",still,confused.
Both solutions works okay in my Pycharm with python 2.7.11.Maybe there are some test cases my solutions did not pass but I can not find it.
First of all, try to use xrange instead of range as this uses less space when the value of nums is very large. Also, you are trying to iterate as well as delete/append a value at the same time in the same array. This is most likely the reason why you are getting the error.
Also, removing a value in the list (if it is not at the end) takes a lot of time because all other elements before it need to moved.
From the first solution: DO NOT modify the list you are iterating. Always brings problems. Better copy the list and modify the list!
class Solution(object):
def findDisappearedNumbers(self, nums):
nums=sorted(list(set(nums)))
nums_copy = nums.copy(nums)
for x in range(1, nums[-1] + 1):
if x in nums:
nums_copy.remove(x)
else:
nums_copy.append(x)
return nums_copy
On the other hand, if num is very large (has many elemente)range can bring problems because it creates the list first (and VERY large lists occupy a LOT of memory). For me cases it is better to xrange than to return a generator.
This does not happen in python3, where the default range returns a generator.
You can use nums = set(nums) which will sort and remove all the duplicates. Then you can run a loop to append all the numbers not present in nums to output array.
Your first solution will fail if the test input is an empty list as num[-1] would give an index out of bound.
Your second solution will be slow as it has to iterate through the list. Would the below solution work? Set operations are optimised. But is the space complexity ok for you?
ret = set(range(1, len(nums)+1))
ret = ret - set(nums)
return list(ret)

How to print list of lists with values having 3 decimal numbers?

a = [[1.0993455308580886, 1.9814814814814814, 1.2331369355392543, 1.646283618833137, 2.2736098709332486, 1.50035992597825]]
I have the list of lists above. How can i print it in order to have the number printed with 3 decimal numbers. I want this:
b = [[1.099, 1.981, 1.233, 1.646, 2.273, 1.500]]
Is there a way so that i can force all float numbers in my code to have 3 decimal numbers?
This is a dup of Change default float print format.
Long story short: you cannot change it globally. But you can write a function such that
return [[round(n, 3) for n in a[0]]]
or
return [['%.3f' % n for n in a[0]]]
Creating lists like this is called list comprehension. Alternatively, you can also use map:
return [map(lambda n: '%.3f' % n, a[0])]
But usually Python developers prefer list comprehension.

How can I remove similar but not duplicate items from a list?

I have a list:
values = [[6.23234121,6.23246575],[1.352672,1.352689],[6.3245,123.35323,2.3]]
What is a way I can go through this list and remove all items that are within say 0.01 to other elements in the same list.
I know how to do it for a specific set of lists using del, but I want it to be general for if values has n lists in it and each list has n elements.
What I want to happen is perform some operation on this list
values = [[6.23234121,6.23246575],[1.352672,1.352689],[6.3245,123.35323,2.3]]
and get this output
new_values = [[6.23234121],[1.352672],[6.3245,123.35323,2.3]]
I'm going to write a function to do this for a single list, eg
>>> compact([6.23234121,6.23246575], tol=.01)
[6.23234121]
You can then get it to work on your nested structure through just [compact(l) for l in lst].
Each of these methods will keep the first element that doesn't have anything closer to it in the list; for #DSM's example of [0, 0.005, 0.01, 0.015, 0.02] they'd all return [0, 0.0.15] (or, if you switch > to >=, [0, 0.01, 0.02]). If you want something different, you'll have to define exactly what it is more carefully.
First, the easy approach, similar to David's answer. This is O(n^2):
def compact(lst, tol):
new = []
for el in lst:
if all(abs(el - x) > tol for x in new):
new.append(el)
return compact
On three-element lists, that's perfectly nice. If you want to do it on three million-element lists, though, that's not going to cut it. Let's try something different:
import collections
import math
def compact(lst, tol):
round_digits = -math.log10(tol) - 1
seen = collections.defaultdict(set)
new = []
for el in lst:
rounded = round(seen, round_digits)
if all(abs(el - x) > tol for x in seen[rounded]):
seen[rounded].add(el)
new.append(el)
return new
If your tol is 0.01, then round_digits is 1. So 6.23234121 is indexed in seen as just 6.2. When we then see 6.23246575, we round it to 6.2 and look that up in the index, which should contain all numbers that could possibly be within tol of the number we're looking up. Then we still have to check distances to those numbers, but only on the very few numbers that are in that index bin, instead of the entire list.
This approach is O(n k), where k is the average number of elements that'll fall within one such bin. It'll only be helpful if k << n (as it typically would be, but that depends on the distribution of the numbers you're using relative to tol). Note that it also uses probably more than twice as much memory as the other approach, which could be an issue for very large lists.
Another option would be to sort the list first; then you only have to look at the previous and following elements to check for a conflict.

More elegant way for updating a slice of a list

Given a list, I would like to apply some set of operations to a subset(slice) of the list, and store the result of each transformation in the original list.
My background is in Ada, which led me to make the following mistake:
Number_List = [0,1,2,3,4,5,6,7,8,9]
for Index, Number in enumerate(Number_List[1:]):
Number_List[Index] = Number + 1
Giving a new Number_List of: 2,3,4,5,6,7,8,9,10,9 and teaching me that a slice of an array is re-indexed to 0.
I've moved to the following, which is cumbersome but functional.
Number_List = [0,1,2,3,4,5,6,7,8,9]
for Index in range(1,len(Number_List))
Number_List[Index] = Number_List[Index]+1
I am looking for a more elegant way to do this.
enumerate takes a start parameter:
Number_List = [0,1,2,3,4,5,6,7,8,9]
for Index, Number in enumerate(Number_List[1:], start=1):
Number_List[Index] = Number + 1
You can also write
Number_List[1:] = [x+1 for x in Number_List[1:]]
from itertools import islice
number_list[start:stop] = (x + 1 for x in islice(number_list, start, stop))
Alternatively, use number_list[start:stop] instead of islice, but that creates another slice needlessly. This updates the list in-places either way thanks to slice assignment and avoids an explicit loop.
You can use list comprehensions and slices to great effect:
vals = range(10) #gives your example numbers
vals[1:] = [v + 1 for v in vals[1:]]