Multiply a list of ints using list comprehension - python-2.7

Is there a way to do this with list comprehension?
for i in range(0, len(x)):
if i == 0:
sum = x[i]
else:
sum = sum * x[i]
I've tried this:
[total for i in x if i == 0 total = x[i] else total = total * x[i]]
and this:
[total = x[i] if i == 0 else total = total * x[i] for i in x]
I saw that there is a way to do it with enumerate but I was wondering if there is a way to do it in one line just using list comprehension. I'm not trying to solve a problem, I'm just curious.

I think what you need is reduce, but not list comprehension.
from operator import mul
s = [1, 2, 3]
print reduce(mul, s, 1)
Or using list comprehension:
class Mul(object):
def __init__(self):
self.product = 1
def __call__(self, x):
self.product *= x
return self.product
s = [1, 2, 3, 4, 5]
m = Mul()
[m(x) for x in s]

I'm gonna prefix this with "you do not want to do this". No really. But if you did...
# whatever your input is
x = [1, 2, 3, 4, 5]
# set the initial total to 1, and wrap it in a list so we can modify it in an expression
total = [1]
# did I mention you shouldn't do this?
[total.__setitem__(0, xi * total.__getitem__(0)) for xi in x]
print total[0]
120

Related

how do you split a list into 3 lists, for each list in a list? Python Beginner

list1= [[1,2,3,4,5,6,7,8,9],[1,2,3,4,5,6,7,8,9],[1,2,3,4,5,6,7,8,9]]
Result should be:
list2 = [[1,2,3],[4,5,6],[7,8,9],[1,2,3],[4,5,6],[7,8,9],[1,2,3],[4,5,6],[7,8,9]]
This should work for any list divisible by 3 as well.
list1 = [1,2,3,4,5,6,7,8,9]
Result:
list2 = [[1,2,3],[4,5,6],[7,8,9]]
I tried using:
list2 = [list1[i:i + n] for i in range(0,len(list1),n)]
No luck.
Answer:
list_1 = [either Nested or not Nested]
check_list_type = any(isinstance(i, list) for i in list_1)
if check_list_type == True:
split_list = [z[j: j + 3] for z in list_1 for j in range(0, len(z) - 2, 3)]
if check_list_type == False:
length = int(len(list_1)/3)
split_list = [list_1[i:i + length] for i in range(0,len(list_1),length)]
print(split_list)
Allows you to split any list into 3 more lists.
Try this:
list2 = [lst[j: j + 3] for lst in list1 for j in range(0, 7, 3)]
A slightly more generic approach:
list2 = [lst[j: j + 3] for lst in list1 for j in range(0, len(lst) - 2, 3)]

Sympy doing subs multiple times

I am using isympy and have the expression:
expr = x + 2 * y
And I want to substitute x with the values in [0, 1, 2, 3]. Currently I am doing:
Eq(Symbol('X_0'), expr.subs(x, 0))
Eq(Symbol('X_1'), expr.subs(x, 1))
Eq(Symbol('X_2'), expr.subs(x, 2))
Eq(Symbol('X_3'), expr.subs(x, 3))
Output:
X₀ = 2⋅y
X₁ = 2⋅y + 1
X₂ = 2⋅y + 2
X₃ = 2⋅y + 3
Is there are a better way to do this? I would like Xₖ to be a function which can take a list of k values.
Use a list comprehension to return a list given a list input:
In [1]: expr=x+2*y
In [2]: [expr.subs(x,i) for i in range(4)]
Out[2]: [2⋅y, 2⋅y + 1, 2⋅y + 2, 2⋅y + 3]
This can of course be cast as a function.

Unique lists in nested list in numba

I would like to find the number of unique lists within a nested list in a nopython numba function, e.g:
from collections import Counter
def number_of_unique_lists_v1(a):
uniques = Counter(tuple(item) for item in a)
number = len(uniques.keys())
return number
print(number_of_unique_lists_v1([[1,2,3],[1,2],[3,4],[1,2,3])
>>> 3
or
def number_of_unique_lists_v2(a):
uniques = [list(x) for x in set(tuple(x) for x in a)]
number = len(uniques)
return number
print(number_of_unique_lists_v2([[1,2,3],[1,2],[3,4],[1,2,3])
>>> 3
Unfortunately, both ideas don't work with #nb.njit. How can I make it work?
Edit:
Using the approach of mpw2 I found that in principle the following code works:
from numba.typed import List
#nb.njit
def number_of_unique_lists_v3():
a = [[1, 2, 3], [1, 2], [3, 4], [1, 2, 3]]
s = List()
for x in a:
if not x in s:
s.append(x)
number = len(s)
return number
print(number_of_unique_lists())
>>> 3
BUT this does not work for me since the list a is created slightly differently in my function, similar as shown in a minimal example below.
from numba.typed import List
#nb.njit
def number_of_unique_lists():
a = [[0] for _ in range(4)]
a[0] = [1, 2, 3]
a[1] = [1, 2]
a[2] = [3, 4]
a[3] = [1, 2, 3]
s = List()
for x in a:
if not x in s:
s.append(x)
number = len(s)
return number
Now I get an error which I don't understand...
Here is one working solution using numba.typed.List() objects
import numba as nb
from numba.typed import List
#nb.njit
def number_of_unique_lists(a):
s = List()
for x in a:
if not x in s:
s.append(x)
number = len(s)
return number
a = [[1,2,3],[1,2],[3,4],[1,2,3]]
typed_a = List()
for x in a:
s = List()
for y in x:
s.append(y)
typed_a.append(s)
print(number_of_unique_lists(typed_a))
>>> 3

Python. <Remove Element> in a list

Title:
172. Remove Element
Description:
Given an array and a value, remove all occurrences of that value in place and return the new length.
The order of elements can be changed, and the elements after the new length don't matter.
My Answer:
On LintCode
def removeElement(self, A, elem):
# write your code here
if A == []:
return A
if elem in A:
sortedA = sorted(A)
li = []
for i in xrange(len(sortedA)):
if sortedA[i] == elem:
li += [i]
newLength = sortedA[:min(li)] + sortedA[max(li)+1:]
return newLength
else:
return A
On my mac
A = [0,4,4,0,0,2,4,4]
elem = 4
def sss(A, elem):
if A == []:
return A
if elem in A:
print A
sortedA = sorted(A)
print sortedA
li = []
for i in xrange(len(sortedA)):
# print type(i)
if sortedA[i] == elem:
li += [i]
print li
newLength = sortedA[:min(li)] + sortedA[max(li)+1:]
print newLength
return newLength
else:
return A
print sss(A, elem)
This answer On my mac work's good, but On LintCode doesn't accept.
Why not use a list comprehension to filter out the unwanted elements?
class Solution:
def removeElement(self, A, elem):
A[:] = [item for item in A if item != elem]
return len(A)
The key here is the slice notation on the left hand side of the assignment. This makes it an "in place" operation, so the original list A is mutated, rather than a copy being made.
Example usage:
>>> l = [1, 2, 3, 4, 4, 5, 4, 10, 11, 4]
>>> len(l)
10
>>> Solution().removeElement(l, 4)
6
>>> l
[1, 2, 3, 5, 10, 11]
>>> len(l)
6
Although this is an old post, yet would like to add the different approaches I tried. Time Complexity is O(n) in all cases.
Method I: Override the elements if they are not val (Logical Approach)
def removeElement(self, nums: List[int], val: int) -> int:
i : int = 0 # This will be an index pointer & will provide the sixe at the end
for j in range(len(nums)):
if nums[j] != val: # if the values are not same
nums[i] = nums[j] # Override the value at location i
i+=1
return i
Method II: Override the val with last array element (Logical Approach)
def removeElement(self, nums: List[int], val: int) -> int:
i: int = 0
n: int = len(nums)
while(i<n):
if(nums[i] == val):
# Replace the element with last array element & reduce the array size by 1
nums[i] = nums[n-1]
n -=1
else:
i +=1
return n
Method III -- Improved form of Method 2 (Python way)
def removeElement(self, nums: List[int], val: int) -> int:
i : int = 0
n : int = len(nums)
while i< n :
print(i, nums, n)
if val in nums[:n]:
i = nums.index(val,0,n)
nums[i] = nums[n-1]
n -=1
else:
break
return n
Method IV -- Python way
def removeElement(self, nums: List[int], val: int) -> int:
nums[:] = [x for x in nums if x !=val]
return len(nums)
All of them have an average runtime of around 36ms and memory utilization around 13.8MB.

How do you count how many maximum values there are in a list?

Lets say I have the list below:
list1=[1,2,4,6,8,3,2,5,8,4,2]
I want to return the integer, 2, because 8 is the maximum value and there are two 8s in the list. How can I do this? Edit: I also want to assume that the maximum number in the list can be any negative or non-negative number including zero.
Well you can use something like this:
list1=[1,2,4,6,8,3,2,5,8,4,2]
print list1.count(max(list1))
ans = 0
mx = 0
for x in list1:
if x > mx:
mx = x
ans = 1
elif x == mx :
ans += 1
print ans
assume max number is bigger than 0, otherwise you should initial mx with the negative infinity
>>> list1=[1,2,4,6,8,3,2,5,8,4,2]
>>> x = max(list1)
>>> l = []
>>> for i in list1:
if i == x:
l.append(i)
>>> l
[8, 8]
>>> len(l)
2
OR
>>> list1=[1,2,4,6,8,3,2,5,8,4,2]
>>> x = max(list1)
>>> result = len(filter(lambda i: i == x, list1))
>>> result
2