Define a function calls addFirstAndLast(x) that takes in a list of numbers and returns the sum of the first and last numbers.
Examples
>>> addFirstAndLast([])
0
>>> addFirstAndLast([2, 7, 3])
5
>>> addFirstAndLast([10])
10
My question is this that i can not use two variables in for loop, so what should i do , how to fix the error. and what could be the improved code of this problem.
def addFirstAndLast(x):
total = 0
total1 = 0
total2 = 0
pos_last = []
for num, last in x:
num = str(num)
num = num[0]
total1 += int(num)
last = last % 10
pos_last = pos_last.append(last)
total = sum(pos_last)
total2 = total+total1
return total2
print addFirstAndLast([2, 7, 3])
3 distinct cases: 1) the list is empty, 2) the list has one element, 3) the list has two or more elements.
Try without loop:
def addFirstAndLast(x):
if len(x) == 0:
return 0
elif len(x) < 2:
return x[0]
else:
return x[0]+x[-1]
>>> print addFirstAndLast([2, 7, 3])
5
>>> print addFirstAndLast([2, 3])
5
>>> print addFirstAndLast([3])
3
x is a list of integers, when using x in a for loop , each iteration would get a single integer. But when you do -
for num, last in x:
You are trying to unpack a single integer into 2 places, this cannot happen, and it is causing your issue.
I am not even sure what the rest of your logic does , you can do this simply using -
def addFirstAndLast(x):
l = len(x)
return x[0] + x[-1] if l > 1 else x[0] if l > 0 else 0
Examples -
>>> addFirstAndLast([])
0
>>> addFirstAndLast([2, 7, 3])
5
>>> addFirstAndLast([10])
10
Explanation of the logic - The expression is -
((x[0] + x[-1]) if l > 1 else x[0]) if l > 0 else 0
It first checks the outer most if condition, if length is 0 it returns 0 , if not it goes onto inner if condition.
In the inner if condition, if length is greater than 1(meaning there are 2 or more elements) it returns sum of first and last, otherwise (which means length is greater than 0 but less than 2 , meaning its 1) it returns first element.
Related
I need to find the sum of the list elements between -1 and -1.
I tried this solution,but it adds the elements 1,2,3 to 1,1,1,1 .Can you help me with a better logic ?
lis = [1,2,3,4,-1,1,1,1,1,-1,1,2,3]
sum = 0
newlis = []
for i in range(0,len(lis)-1):
if lis[i] == -1:
while i+1 < len(lis) and lis[i+1]!=-1:
sum = sum+lis[i+1]
i = i+1
print(sum)
You can use:
idx = [i for i, v in enumerate(lis, 1) if v == -1]
print(sum(lis[idx[0]:idx[1]-1]))
# 4
Demo
Here's an example that works without lambda
lis = [1,2,3,4,-1,1,1,1,1,-1,1,2,3]
first = lis.index(-1) + 1
second = lis[first:].index(-1) + first
result = sum(lis[first:second])
One approach is that you could create a boolean flag which sets to true when you see a -1 and set it back to false when you see the second -1 (or break). You add the numbers if the flag is true.
lis = [1,2,3,4,-1,1,1,1,1,-1,1,2,3]
sum = 0
flag = False;
for i in range(len(lis)):
if not flag:
if lis[i] == -1:
flag = True
elif lis[i] == -1:
flag = False #this line could be omitted
break
else:
sum += lis[i]
print(sum)
We can first compute the indexes where -1 appears:
In [12]: l = [1,2,3,4,-1,1,1,1,1,-1,1,2,3]
In [16]: indexes = [index for index in range(len(l)) if l[index] == -1]
In [17]: indexes
Out[17]: [4, 9]
Now, we know that -1 appears at indexes 4 & 9. To verify that we have the right set of numbers:
In [20]: l[indexes[0]:indexes[1]]
Out[20]: [-1, 1, 1, 1, 1]
So, computing the sum is easier now:
In [19]: sum(l[indexes[0]:indexes[1]])
Out[19]: 3
Did you mean this?
sum(filter(lambda n: -1 <= n <= 1, lis))
or without lambda:
def f(n):
return -1 <= n <= 1
sum(filter(f, lis))
You can use lis.index to find the first -1. It also offers a second parameter for where to start the search, so you can also use it to find the second -1. Then just get the slice between them and sum it.
>>> start = lis.index(-1) + 1
>>> stop = lis.index(-1, start)
>>> sum(lis[start:stop])
4
I am given a problem to solve ! which is
A non-empty array A consisting of N integers is given. The array contains an odd number of elements, and each element of the array can be paired with another element that has the same value, except for one element that is left unpaired.
For example, in array A such that: A[0] = 9 A[1] = 3 A[2] = 9 A[3] = 3 A[4] = 9 A[5] = 7 A[6] = 9
the elements at indexes 0 and 2 have value 9,
the elements at indexes 1 and 3 have value 3,
the elements at indexes 4 and 6 have value 9,
the element at index 5 has value 7 and is unpaired.
Write a function:
def solution(A)
that, given an array A consisting of N integers fulfilling the above conditions, returns the value of the unpaired element.
For example, given array A such that:
A[0] = 9 A[1] = 3 A[2] = 9
A[3] = 3 A[4] = 9 A[5] = 7
A[6] = 9
the function should return 7, as explained in the example above.
Write an efficient algorithm for the following assumptions:
N is an odd integer within the range [1..1,000,000];
each element of array A is an integer within the range [1..1,000,000,000];
all but one of the values in A occur an even number of times.
I think I am only half way to solve the problem:
def findOddItem(A):
for i, item in enumerate(A): # look to left not immidiate one
if A[i] != A[i - 2]:
print A[i]
but this looks like printing the wrong result..
I would go with reduce() (moved to functools.reduce() in Python 3.x) in combination with operator.xor():
# Uncomment for Python 3.x:
# from functools import reduce
import operator
def solution(A):
return reduce(operator.xor, A)
arr = [9, 3, 9, 3, 9, 7, 9]
print(solution(arr)) # 7
It's an, as clean as it gets, O(n) solution.
You could use "or" bitwise operator. Since all elements occur twice except one element they would cancel each other leaving the element that has occurred only once.
def findSingleOccurance( arr, n):
res = arr[0]
# Do XOR of all elements and return
for i in range(1,n):
res = res ^ arr[i]
return res
Time complexity O(n) Space Complexity O(1).
Hope this helps.
Since there is no condition that all but one elements occur twice, I guess it could also mean 4, 6, ... , times.
In this case, I would rather use numpy.bincount to see which integer has an odd count.
a = [1,1,2,2,3,3,5,3,3,4,5,5,5,10,10]
a_cnt = list(numpy.bincount(a))
for i in a_cnt:
if i != 0 and i%2 == 1:
print(a_cnt.index(i))
# 4
You could use "xor" bitwise operator. Since all elements occur twice except one element they would cancel each other leaving the element that has occurred only once.
def SingleOccurance( arr, n):
result = arr[0]
# Do XOR of all elements and return as 'a' xor 'a' is 0 and except single
# occured number rest will turn to 0 and 'a' xor 0 is 'a'
for i in range(1,n):
result = res ^ arr[i]
return result
Or
We can sum the bits in the same positions for all the numbers and take modulo with 3. The bits for which sum is not multiple of 3, are the bits of number with a single occurrence.
Let us consider the example array {5, 5, 5, 8}. The 101, 101, 101, 1000
Sum of first bits%3 = (1 + 1 + 1 + 0)%3 = 0
Sum of second bits%3 = (0 + 0 + 0 + 0)%0 = 0
Sum of third bits%3 = (1 + 1 + 1 + 0)%3 = 0
Sum of fourth bits%3 = (1)%3 = 1
Hence number which appears once is 1000
Code:
INT_SIZE = 32
def getSingle(arr, n) :
# Initialize result
result = 0
# Iterate through every bit
for i in range(0, INT_SIZE) :
# Find sum of set bits at ith position in all array elements
sm = 0
x = (1 << i)
for j in range(0, n) :
if (arr[j] & x) :
sm = sm + 1
# The bits with sum not multiple of 3, are the
# bits of element with single occurrence.
if (sm % 3) :
result = result | x
return result
def adjacentElementsProduct(inputArray):
i = 0
n = []
t = int(0)
b = int(1)
while i < len(inputArray):
noob = inputArray[t] * inputArray[b]
t += 1
b += 1
i += 1
n.append(noob)
return n
print(adjacentElementsProduct([3, 6, -2, -5, 7, 3]))
Can some one help me when I try to execute this its return
IndexError: list index out of range
Sorry for my bad English Grammar
You need to change your loop so that i only iterates up to len(inputArray) - 1.
Like this:
def adjacentElementsProduct(inputArray):
i = 0
n = []
t = 0
b = 1
while i < len(inputArray) - 1:
noob = inputArray[t] * inputArray[b]
t += 1
b += 1
i += 1
n.append(noob)
return n
print(adjacentElementsProduct([3, 6, -2, -5, 7, 3]))
This is because your noob array is essentially just each adjacent pair of elements in inputArray. Naturally, the number of pairs in a list of i elements is i - 1. This means that you need to change your loop to stop one iteration before, as it's throwing the IndexError when t is the len(inputArray) - 1 and b is the len(inputArray) (b isn't a valid value in the last iteration of your current code as there's not that many elements).
Here you set i=0, t=0, and b=1, thus your b always greater than i by 1. So, in the last loop (where t and i should equal len(inputArray) -1), the value of b should be len(inputArray) which is bigger than the length of your array.
I am not very sure about your excepted output, but I guess you could fix it like following:
while i < len(inputArray) - 1:
noob = inputArray[t] * inputArray[b]
t += 1
b += 1
i += 1
n.append(noob)
You can change the while loop for a for loop and use try / except to return the result when it reaches the end of the iteration. You can also add in extra except clauses to catch other errors and make use of else and finally if needs be .. https://docs.python.org/3/tutorial/errors.html
def adjacentElementsProduct(inputArray):
i = 0
n = []
t = int(0)
b = int(1)
for i in range(len(inputArray)):
try:
noob = inputArray[t] * inputArray[b]
t += 1
b += 1
i += 1
n.append(noob)
except IndexError:
return n
return n
print(adjacentElementsProduct([3, 6, -2, -5, 7, 3]))
l=[3, 6, -2, -5, 7, 3]
print([x*y for x,y in zip(l,l[1:])])
Here zip is used to create the adjacency pair
if I have two list
one named "base" and is used to breakdown another list
another is "match"
like below
base = [4,7,13,14,19]
match = [1,2,5,9,10,12,15,18]
i want to count how many numbers of "match" are within two objects of "base", and store in another list, called "result"
So the "result" should be [1,3,0,2]
I used this way
fianl_num = []
m = 0
countnum = 0
for j in match:
if j < base[m]:
countnum += 1
else:
m = m+1
fianl_num.append(countnum)
countnum = 0
print(fianl_num)`
However, there is a problem, if the match's object is bigger than base's object, the current match's object will be considered else and move on to compare next match's object to the next base's object. As a result, the current base's object is skip
for my example/base = [4,7,13,14,19]/match = [1,2,5,9,10,12,15,18]
my code results in [2,0,2,0]
because 5 is bigger than 4, so it moves on to compare 9 to 7, skip the process comparing 5 to 7
Use sum() to determine the number of elements in match between i and i+1 elements of base.
for i in range(len(base)-1):
count=sum(base[i]<x<base[i+1]for x in match)
l.append(count)
Output:
[1,3,0,2]
There can be better ways for this. But 1 way can be like this:
base = [4,7,13,14,19]
match = [1,2,5,9,10,12,15,18]
l = []
i = 0
while i < len(base)-1:
count = 0
for a in match:
if base[i] < a < base[i+1]:
count += 1
l.append(count)
i += 1
print l
Output:
[1, 3, 0, 2]
How about this?
base = [4,7,13,14,19]
match = [1,2,5,9,10,12,15,18]
fianl_num = []
m = 0
len = len(match)
countnum = 0
for j in base:
while m < len and match[m] < j:
m = m+1
countnum += 1
if j > base[0]:
fianl_num.append(countnum)
countnum = 0
print(fianl_num)
#[1, 3, 0, 2]
I think the one line list comprehension is easier to understand than the problem description:
base = [4,7,13,14,19]
match = [1,2,5,9,10,12,15,18]
[sum(1 for e in match if lower < e < upper) for lower, upper in zip(base, base[1:])]
Out[7]: [1, 3, 0, 2]
can be a few char shorter if you are OK with the summing of bools (True = 1, False = 0) as in Trelzevir's answer
[sum(lower < e < upper for e in match) for lower, upper in zip(base, base[1:])]
older python versions may need extra braces for sum's arg to be recognized as a generator
I'm trying to make a function that returns the index of the smallest element whose sum along all the elements to its left is bigger than a number x.
How can I do this in a Pythonic way?
Example:
I have a list of numbers [32, 6, 12] and I'm trying to make a function that would return 0 if x < 32, 1 if x < 32 + 6 and 2 if x < 32 + 6+ 12
A non-Pythonic way would be:
a = [23,3,32]
i = 0
summ = 0
found = False
def example(e):
while not found:
if e <= (a[i] + summ):
found = True
element = i
else:
summ += a[i]
i += 1
return element
def find_index(a, x):
for i, e in enumerate(a):
x -= e
if x < 0:
return i
return i
There's a very nice functional way to do this:
import itertools
import operator
xs = [32, 6, 12]
target = 5
next(i for i, x in enumerate(itertools.accumulate(xs, operator.add)) if x > target)
At the end of the list it raises StopIteration.
Found a different solution
>>> xs = [18,30,307]
>>> element = 40
>>> target = [sum(xs[:i+1]) for i, elem in enumerate(xs)]
>>> target.index((i for i in target if i>element).next())
1
With filter
>>> target.index(filter(lambda x: x > element, target)[0])
1
With filter + generator
>>> import itertools
>>> target.index(itertools.ifilter(lambda x: x > element, target).next())
1