I am trying to find the average of certain numbers in python
For example:
A={('A','B',1):1,('A','B',2):4,('A1','B1',2):5,('A1','B1',1):6}
A is dictionary and my output should be
B={('A','B'):1+4/2,('A1','B1'):11/2)}
I got the logic by using some FOR loops and IF condition but it is too time consuming.
Can anyone tell me a faster way of getting the output.
my logic
for i in A:
# lis.append(i)
lis.append((i, A[i]))
for j in lis:
if (j[0][0], j[0][1]) not in pro_loc_comb:
pro_loc_comb.append((j[0][0], j[0][1]))
B= {}
print pro_loc_comb
for x in pro_loc_comb:
a = 0
count = 0
for j in lis:
if (x[0] == j[0][0]):
if (x[1] == j[0][1]):
count = count + 1
a = (a + j[1])
B[(x[0], x[1])] = a / float(count)
print B
Thanks in advance
Since you didn't include your solution, I used this:
from __future__ import division
A={('A','B',1):1,('A','B',2):4,('A1','B1',2):5,('A1','B1',1):6}
B={}
C={}
for x in A:
val= A[x]
y,z,n=x
if (y,z) in B:
B[(y,z)]+=val
C[(y,z)]+=1
else:
B[(y,z)]=val
C[(y,z)]=1
for x in B:
B[x]=B[x]/C[x]
Related
Here is the given assignment + code:
Write a function even_value_set(list1, list2, list3), which receives
three lists containing integer items as arguments. The function
creates and returns a set that contains all items with even value from
all three lists.
def test():
l = [[],[],[]]
for i in range(3):
for j in range(random.randint(7,14)):
l[i].append(random.randint(1,35))
print ("List" + str(i + 1) +":",l[i])
print ("")
s = even_value_set(l[0],l[1],l[2])
print ("Return type:", str(type(s)).replace("<","").replace(">",""))
print ("Set with even values only:", end = "")
print (set(sorted(list(s))))
test()
import random
I tried using .union() and making adding lists into another before turning them into sets, but didn't have any luck.
You can do this in a simply pythonic way. This function can be written as a simple oneliner using comprehension
def even_value_set(list1, list2, list3):
return set([num for num in list1+list2+list3 if num % 2 == 0])
Basically, what we did here is concatenated all lists, fitered even numbers and then made it into a set.
You can union lists (with duplicates) with the + operation.
union_list = list1 + list2 + list3
If you only want the unique values you can call set on this list.
unique_set = set(union_list)
Now you can create a new empty set and iterate over the unqiue_set and add all the even values:
solution = set()
for v in unique_set:
if v%2==0:
solution.add(v)
def even_value_set(*lsts):
s = set()
for lst in lsts:
s |= {x for x in lst if x % 2 == 0}
return s
Also you can use starring
def even_value_set(*lsts):
return set().union(*[{x for x in lst if x % 2 == 0} for lst in lsts])
And solution with concatenation (more memory).
set comprehension is more effective than set()
def even_value_set(l1, l2, l3):
return {x for x in l1+l2+l3 if x % 2 == 0}
You can make the union of lists using +, like list1 + list2. Then just walk through the result list checking if the number is even and adding in another list.
def even_value_set(list):
result = set()
for val in list:
if val%2 == 0:
result.add(val)
return result
def test():
l = [[],[],[]]
for i in range(3):
for j in range(random.randint(7,14)):
l[i].append(random.randint(1,35))
print ("List" + str(i + 1) +":",l[i])
print ("")
uni = l[0] + l[1] + l[2]
s = even_value_set(uni)
print ("Return type:", str(type(s)).replace("<","").replace(">",""))
print ("Set with even values only:", end = "")
print (set(sorted(list(s))))
test()
import random
Is it what you want? I think your question is confusing.
I don't know why, but I am getting value of scope as final as 0 even len(s) as zero in the last line of countfrequency(s) function.
import collections
def countfrequency(s):
final = 0
flag = 1
d = dict(collections.Counter(s))
for item in d:
if d[item] <= k:
flag = 0
if flag == 1: #Here
final = max(final, len(s))
print(final)
s = "ababbc"
k = 2
for x in range(len(s)):
for y in range(1, len(s)):
countfrequency(s[x:y + 1])
It is because of 2 reasons :
Value of flag is 0 at last so it wont change the value of final
Length function takes object as a parameter and when unchanged it gives 0
So you can can either make flag 1 so that control goes inside if condition or print the value of len(s) out side the if condition
In addition to the answer posted by shaktiraj jadeja, the modified code is as follows:
import collections
def countfrequency(s, k):
final = 0
flag = 0
d = dict(collections.Counter(s))
# print(d)
for item in d:
if d[item] > k:
flag = 1
break
if flag == 1: #Here
# print("Inside:", final, len(s))
final = max(final, len(s))
print(final)
s = "ababbc"
k = 2
for x in range(len(s)):
for y in range(1, len(s)):
# print(s[x:y])
countfrequency(s[x:y + 1], k)
To start with there is no problem of scope.
Now lets get back to the problem
Lets define a rule.
Rule: If a sub string has each character repeated more than k(=2) times in it. Then it is a good substring. Else it is a bad substring
Then your code simply prints the length of good sub string or 0 in case of bad substring
In short in your example string s= "ababbc" contains no good substring
if you try S = "aaaaaa" you will see many numbers printed other than 0 (exactly 11 0's and 10 other numbers)
Now either this was your confusion or you wrote the wrong code for some logic
I hope this helps
I'm writing a program that writes two lists of five numbers between 0-9. I need the program to compare the lists to find how many numbers the lists have in common, but I'm not sure how.
Edit: I just need the program to write the amount of numbers in common, I don't need the numbers themselves
import random
X = 0
while X<2000:
House_deal = [random.randint(0,9) for House_deal in range(5)]
Player_deal = [random.randint(0,9) for House_deal in range(5)]
print("House numbers: ", House_deal)
print("Player numbers: ", Player_deal)
print(" ")
X += 1
Assuming we have l_one and l_two for two randomly generated lists.
counter = [0] * 10
answer = 0
for x in l_one:
counter[x] += 1
for x in l_two:
if counter[x] > 0:
counter[x] -= 1
answer += 1
print(answer)
This algorithm works in O(n) compared to O(n^2) solutions posted before.
A solution similar to others already posted, but using Counter:
import random
from collections import Counter
for _ in range(2000):
House_deal = [random.randint(0,9) for _ in range(5)]
Player_deal = [random.randint(0,9) for _ in range(5)]
hc = Counter(House_deal)
pc = Counter(Player_deal)
common = hc.keys() & pc.keys() #get the intersection of both keys
counts = 0
for cel in common:
counts += min(hc[cel], pc[cel])
print("House numbers: ", House_deal)
print("Player numbers: ", Player_deal)
print("Common numbers: ", counts)
I also changed the while loop into a for loop.
You could define a function like the ones here and use the len() function to get the number of elements in the list. The functions cast the lists to sets and get the intersections of them, which would be all the elements in common. That way you can also see the elements that are incommon between them if you decide you want to as well, or you can even modify this to subtract one list from the other to get the elements they don't have in common like here. Let me know if this is what you're looking for.
You can use a function as follows:
def compare(list1 , list2):
common_list = []
for i in list1:
if i in list2:
common_list.append(i)
print(len(common_list)) # Number of common elements
Its work:
import random
list_one = random.sample(range(9), 4)
list_two = random.sample(range(9), 4)
print(list_one)
print(list_two)
count = 0
for item_one in list_one:
for item_two in list_two:
if item_one == item_two:
count +=1
print(count)
Ps.: The instruction for item_two in list_two: maybe change by if item_one in list_two:, but as you seem to be a beginner, I put it even more explicitly.
A variant of the previous answer.
counter_1 = {k, 0 : k in l_one}
counter_2 = {k, 0 : k in l_two}
answer = 0
for x in l_one:
counter_1[x] = counter_1[x] + 1
for x in l_two:
counter_2[x] = counter_2[x] + 1
for x, v1 in counter_1.items():
v2 = counter_2.get(x, 0)
answer = answer + min (v1, v2)
print(answer)
You can use the set data type in Python, and do something like
In [1]: from random import randint
In [2]: import random
In [3]: random.seed(123)
In [4]: x = set([randint(0,9) for x in range(5)])
In [5]: y = set([randint(0,9) for x in range(5)])
In [6]: x
Out[6]: {0, 1, 4, 6}
In [7]: y
Out[7]: {0, 1, 6, 8}
In [8]: cnt = len(x & y) # return the amount of numbers in common, e.g. {0, 1, 6}
In [9]: cnt
Out[9]: 3
Hope it helps.
If n = 4, m = 3, I have to select 4 elements (basically n elements) from a list from start and end. From below example lists are [17,12,10,2] and [2,11,20,8].
Then between these two lists I have to select the highest value element and after this the element has to be deleted from the original list.
The above step has to be performed m times and take the summation of the highest value elements.
A = [17,12,10,2,7,2,11,20,8], n = 4, m = 3
O/P: 20+17+12=49
I have written the following code. However, the code performance is not good and giving time out for larger list. Could you please help?
A = [17,12,10,2,7,2,11,20,8]
m = 3
n = 4
scoreSum = 0
count = 0
firstGrp = []
lastGrp = []
while(count<m):
firstGrp = A[:n]
lastGrp = A[-n:]
maxScore = max(max(firstGrp), max(lastGrp))
scoreSum = scoreSum + maxScore
if(maxScore in firstGrp):
A.remove(maxScore)
else:
ai = len(score) - 1 - score[::-1].index(maxScore)
A.pop(ai)
count = count + 1
firstGrp.clear()
lastGrp.clear()
print(scoreSum )
I would like to do that this way, you can generalize it later:
a = [17,12,10,2,7,2,11,20,8]
a.sort(reverse=True)
sums=0
for i in range(3):
sums +=a[i]
print(sums)
If you are concerned about performance, you should use specific libraries like numpy. This will be much faster !
A = [17,12,10,2,7,11,20,8]
n = 4
m = 3
score = 0
for _ in range(m):
sublist = A[:n] + A[-n:]
subidx = [x for x in range(n)] + [x for x in range(len(A) - n, len(A))]
sub = zip(sublist, subidx)
maxval = max(sub, key=lambda x: x[0])
score += maxval[0]
del A[maxval[1]]
print(score)
Your method uses a lot of max() calls. Combining the slices of the front and back lists allows you to reduce the amounts of those max() searches to one pass and then a second pass to find the index at which it occurs for removal from the list.
Solving the Smoothing the Weather problem on Codeabbey. It prints the correct output for the first 32 values after which it doesn't read the inputted values correctly. Inputted test values are well over 150.
Here is my code:
from __future__ import division
num=int(raw_input());
inp=((raw_input()).split(" "));
lists=[];
for i in inp:
if inp.index(i)==0 or inp.index(i)==len(inp)-1:
lists.append(inp[inp.index(i)])
else:
a,b,c=0.0,0.0,0.0;
a=float(inp[(inp.index(i))+1])
b=float(inp[inp.index(i)])
c=float(inp[(inp.index(i))-1])
x=(a+b+c)/3
x = ("%.9f" % x).rstrip('0')
lists.append(x)
for i in lists:
print i,
The index in the following code will always return the first occurrence of i in inp. So, if there are duplicate values in inp, then the whole logic fails.
if inp.index(i)==0 or inp.index(i)==len(inp)-1:
lists.append(inp[inp.index(i)])
The correct approach would be to enumerate and us correct indices:
from __future__ import division
num = int(raw_input())
inp = ((raw_input()).split(" "))
lists = []
for i, item in enumerate(inp): # This will loop through inp, while filling the next item in item and keep on incrementing i each time starting with 0
if i == 0 or i == len(inp)-1:
lists.append(inp[i])
else:
a = float(inp[i+1])
b = float(inp[i])
c = float(inp[i-1])
x = (a+b+c) / 3.0
x = ("%.9f" % x).rstrip('0')
lists.append(x)
for i in lists:
print i,
Hope that helps.