i have test list
a = [1,2,3,4,5,6,7,8,9,10]
for example, i want to squared some of them and get sum of them. then i want to divide this sum to 2. and then i want raise to the power 1/4
code is:
result = ((a[0]**2+a[1]**2)/2)**(1/4)
prolbem is that i define each value. in this example its a[0] and a[1]
i want just get some variable of number of iterable objects (in my case it's n = 2)
for n = 3 its should be equal to:
((a[0]**2+a[1]**2+a[2]**2)/2)**(1/4)
i can get this values with
for i in range(3):
print(a[i])
with output:
1
2
3
but idk how to add them to my math operation code
This should do it:
square=0
for i in range(3):
square=square+a[i]**2
if i==2:
square=(square/2)**(1/4)
print(square)
This squares each number and adds it to the square variable. If it is on the last iteration of i, it divides square by 2 and raises it to the power of 1/4
You can create a dictionary of operations to perform and apply them on part of your list.
this needs python 3.7+ to guarantee insert-order of rules in dict == order they get applied later:
a = [1,2,3,4,5,6,7,8,9,10]
# rules
ops = {"square_list" : lambda x: [a**2 for a in x], # creates list
"sum_list" : lambda x : sum(x), # skalar
"div_2" : lambda x : x/2, # skalar
"**1/4" : lambda x: x**(1/4)} # skalar
n_min = 0
for m in range(1,len(a)):
# get list part to operate on
parts = a [n_min:m]
print(parts)
# apply rules
for o in ops:
parts = ops[o](parts)
# print result
print(parts)
Output:
[1]
0.8408964152537145
[1, 2]
1.2574334296829355
[1, 2, 3]
1.6265765616977856
[1, 2, 3, 4]
1.9679896712654303
[1, 2, 3, 4, 5]
2.2899878254809036
[1, 2, 3, 4, 5, 6]
2.597184780029334
[1, 2, 3, 4, 5, 6, 7]
2.892507608519078
[1, 2, 3, 4, 5, 6, 7, 8]
3.1779718278112656
[1, 2, 3, 4, 5, 6, 7, 8, 9]
3.4550450628484315
Related
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 have 3 lists.
A_set = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Q_act = [2, 3]
dur = [0, 4, 5, 2, 1, 3, 4, 8, 2, 3]
All lists are integers.
What I am trying to do is to compare Q_act with A_set then obtain the indices of the numbers that match from A_set.
(Example:
Q_act has the elements [2,3]
it is located in indices [1,2] from A_set)
Afterwards, I will use those indices to obtain the corresponding value in dur and store this in a list called p_dur_Q_act.
(Example: using the result from the previous example, [1,2]
The values in the dur list corresponding to the indices [1,2] should be stored in another list called p_dur_Q_act
i.e. [4,5] should be the values stored in the list p_dur_Q_act)
So, how do I get the index of the common integer element (which is [1,2]) from two separate lists and plug it to another list?
So far here are the code(s) I used:
This one, I wrote because it returns the index. But not [4,5].
p_Q = set(Q_act).intersection(A_set)
p_dur_Q_act = [i + 1 for i, x in enumerate(p_Q)]
print(p_dur_Q_act)
I also tried this but I receive an error TypeError: argument of type 'int' is not iterable
p_dur_Q_act = [i + 1 for i, x in enumerate(Q_act) if any(elem in x for elem in A_set)]
print(p_dur_Q_act)
Another option is to use the enumerate iterator to generate every index, and then select only the ones you want:
a_set = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
q_act = [2, 3]
dur = [0, 4, 5, 2, 1, 3, 4, 8, 2, 3]
p_dur_q_act = [i for i,v in enumerate(a_set) if v in q_act]
print([dur[p] for p in p_dur_q_act if p in dur]) # [4, 5]
This is more efficient than repeatedly calling index if the number of matches is large, because the number of calls is proportional to the number of matches, but the duration of calls is proportional to the length of a_set. The enumerate approach can be made even more efficient by turning q_act into a set, since in scales better with sets than lists. At these scales, though, there will be no observable difference.
You don't need to map these to index values, though. You can get the same result if you use zip to map a_set to dur and then select the d values whose a values are in q_act.
a_set = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
q_act = {2, 3}
dur = [0, 4, 5, 2, 1, 3, 4, 8, 2, 3]
p_dur_q_act = [d for a, d in zip(a_set, dur) if a in q_act]
Use index function to get the index of the element in the list.
>>> a_set = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> q_act = [2, 3]
>>> dur = [0, 4, 5, 2, 1, 3, 4, 8, 2, 3]
>>>
>>> print([dur[a_set.index(q)] for q in set(a_set).intersection(q_act)])
[4, 5]
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)
i want to write a function that takes in a list of numbers (positive integers) and returns a list of sorted numbers such that odd numbers come first and even numbers come last
For example:
my_sort([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) => [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
my_sort([1, 2]) => [1, 2]
my_sort([2, 1]) => [1, 2]
my_sort([3, 3, 4]) => [3, 3, 4]
my_sort([90, 45, 66]) => [45, 66, 90]'''
This is my code
def my_sort(numbers):
a = [n for n in numbers if n % 2 != 0]
b = [n for n in numbers if n % 2 == 0]
new_num = b + a
for m in numbers:
if a and b:
return new_num
else:
return "Invalid sorted output"
Which fails all the test. I'm new to programming and python. So I'ld appreciate if anyone could help me with this.
And here is the unittest
import unittest
class MySortTestCases(unittest.TestCase):
def setUp(self):
self.result1 = my_sort([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
self.result2 = my_sort([1, 2])
self.result3 = my_sort([2, 1])
self.result4 = my_sort([3, 3, 4])
self.result5 = my_sort([90, 45, 66])
def test_output_1(self):
self.assertEqual(self.result1, [1, 3, 5, 7, 9, 2, 4, 6, 8, 10],
msg='Invalid sorted output')
def test_output_2(self):
self.assertEqual(self.result2, [1, 2], msg='Invalid sorted
output')
def test_output_3(self):
self.assertEqual(self.result3, [1, 2], msg='Invalid sorted
output')
def test_output_4(self):
self.assertEqual(self.result4, [3, 3, 4], msg='Invalid sorted
output')
def test_output_5(self):
self.assertEqual(self.result5, [45, 66, 90], msg='Invalid
sorted output')
You could so it by splitting the list into odd and even and then sorting both and concatenating the two lists.
def my_sort(numbers):
odd = [n for n in numbers if n % 2 != 0]
even = [n for n in numbers if n % 2 == 0]
return sorted(odd) + sorted(even)
See that this
>>> my_sort([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
[1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
But using a key function avoids constructing the split lists:
>>> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> numbers.sort(key=lambda v: (v%2==0, v))
>>> numbers
[1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
This sorts the list using a key function that returns a tuple of (0, v) if v is odd and (1, v) if even. This causes the odd numbers to appear before the even numbers in an ascending ordered sort.
It can be turned into a function:
def my_sort(numbers):
return sorted(numbers, key=lambda v: (v%2==0, v))
So, I went ahead and grabbed your code and did just a few tests by myself to see the actual output. Your code doesn't actually sort the list currently. It only puts the even numbers first and the odd numbers second. Which by the sound of it isn't what you want either.
>>> my_sort([4, 5, 7, 1, 2, 6, 3])
[4, 2, 6, 5, 7, 1, 3]
>>> my_sort([1, 2])
[2, 1]
These were the outputs I got by running your code using the Python interpreter. As you can see the even numbers are first, unsorted, followed by the odd numbers, also unsorted. This just has to do with the way you made the new_num list. You have new_num = b + a, but you created b by looking for all the even numbers b = [n for n in numbers if n % 2 == 0] and created a by looking for all the odd numbers a = [n for n in numbers if n % 2 != 0]. The % returns the remainder. So, if a number is divisible by 2 it returns 0 and this means that it is even. So, you can either flip the assignment of a and b or you can flip when you add them together so a is first and b is second.
As for the individual chunks not being sorted. Python has a built in sorted function that you can call on list sorted(my_list) that returns a sorted version of that list. So, if you just run that on your a and b when you're adding them together to create your new_num list then the numbers for each should be sorted just fine.
Your if statements at the end inside your for loop are also not working properly. Giving an already sorted list just returns the list given. Your code here:
for m in numbers:
if a and b:
return new_num
else:
return "Invalid sorted output"
This is looping through the original list given and returns the new_num if a and b exists. Since a and b will always exist this will always return new_num and never the "Invalid sorted output" statement. You need to make sure you're checking to see if the numbers list is already sorted with the expected output of your function. My suggestion would be check to see if new_num is the same as numbers.
Just use sorted twice. First to sort the list, and again to sort it by odd then even using the key parameter.
x = [3,5,4,1,6,8,10,2,9,7]
sorted(sorted(x), key=lambda x: (x+1)%2)
# returns:
# [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
This should work... It makes sense if you are joining Andela.
def my_sort(theNumbers):
#pass
evenNumbers=[]
oddNumbers=[]
#CHECK IF EVEN OR ODD THEN STORE THEN SEPARATE
for i in theNumbers:
if i%2==0:
evenNumbers.append(i)
else:
oddNumbers.append(i)
#print (evenNumbers)
#SORT DEM LISTS
evenNumbers.sort()
oddNumbers.sort()
#print (evenNumbers)
#join the two
oddNumbers+=evenNumbers
print (oddNumbers)
#my_sort([11111, 1, 11, 979749, 1111, 1111])
This code will sort even and odd numbers without creating a temporary list.
def segregateEvenOdd(arr, index=0, iterations=0):
if iterations == len(arr):
return arr
if arr[index]%2 == 0:
arr.append(arr[index])
arr.pop(index)
return segregateEvenOdd(arr, index, iterations+1 )
if arr[index]%2 != 0:
return segregateEvenOdd(arr,index+1,iterations+1)
arr = [ 2, 3, 9, 45, 2, 5, 10, 47 ]
output = segregateEvenOdd(arr)
print(output)
# Output
# [3, 9, 45, 5, 47, 2, 2, 10]
This code should work:
def sort_integers(list_of_integers):
odd_numbers = [n for n in list_of_integers if n%2!=0]
odd_numbers = sorted(odd_numbers, reverse = True)
print(odd_numbers)
even_numbers = [x for x in list_of_integers if x%2 == 0]
even_numbers = sorted(even_numbers, reverse = True)
print(even_numbers)
new_sorted_list = even_numbers + odd_numbers
print(new_sorted_list)
I am trying remove duplicate elements from the list, whose number of duplicates is odd.
For example for the following list: [1, 2, 3, 3, 3, 5, 8, 1, 8] I have 1 duplicated 2 times, 3 duplicated 3 times, and 8 duplicated 2 times. So 1 and 8 should be out and instead of 3 elements of 3 I need to leave only 1.
This is what I came up with:
def remove_odd_duplicates(arr):
h = {}
for i in arr:
if i in h:
h[i] += 1
else:
h[i] = 1
arr = []
for i in h:
if h[i] % 2:
arr.append(i)
return arr
It returns everything correctly: [2, 3, 5], but I do believe that this can be written in a nicer way. Any ideas?
You can use collections.Counter and list comprehension, like this
data = [1, 2, 3, 3, 3, 5, 8, 1, 8]
from collections import Counter
print [item for item, count in Counter(data).items() if count % 2]
# [2, 3, 5]
The Counter gives a dictionary, with every element in the input iterable as the keys and their corresponding counts as the values. So, we iterate over that dict and check if the count is odd and filter only those items out.
Note: The complexity of this solution is still O(N), just like your original program.
If order doesn't matter:
>>> a = [1, 2, 3, 3, 3, 5, 8, 1, 8]
>>> list(set([x for x in a if a.count(x)%2 == 1]))
[2, 3, 5]
The list comprehension [x for x in a if a.count(x)%2 == 1] returns only the elements which appear an odd number of times in the list. list(set(...)) is a common way of removing duplicate entries from a list.
you can possibly use scipy.stats.itemfreq:
>>> from scipy.stats import itemfreq
>>> xs = [1, 2, 3, 3, 3, 5, 8, 1, 8]
>>> ifreq = itemfreq(xs)
>>> ifreq
array([[1, 2],
[2, 1],
[3, 3],
[5, 1],
[8, 2]])
>>> i = ifreq[:, 1] % 2 != 0
>>> ifreq[i, 0]
array([2, 3, 5])