Multiplying random numbers in list in python - python

Ok so i need to multiple 50 numbers that were randomly generated, between 5 and 70, and put in a list. I am able to create the list of numbers but dont know how to.
Example-If the list generates the numbers [10, 12, 3] the answer would be 360 as 10*12*3 = 360
This is the code i am working with.
import random
talnalisti = []
for x in range(50):
tala = random.randint(5, 70)
talnalisti.append(tala)
print(talnalisti)
print("Stærsta talan er", max(talnalisti))
print("Minsta talan er", min(talnalisti))

You could declare a variable beforehand and directly multiply the newly generated random number to it.
import random
talnalisti = []
res = 1
for x in range(50):
tala = random.randint(5, 70)
talnalisti.append(tala)
res *= tala
Or you could use a normal for-loop to loop over the elements afterwards.
res = 1
for x in talnalisti:
res *= x
Keep in mind that there are many other and more sophisticated solutions.

No complex code needed to get the product of list elements, try this:
product = 1 # to get first element unchanged
for element in talnalisti:
product = product*element
print(product)
Tested, printed something like: 98135262633757341182160114591148916792761926172600487116800000000000000000

Try this:
import random
from functools import reduce
talnalisti = []
for x in range(50):
tala = random.randint(5, 70)
talnalisti.append(tala)
product_ = reduce((lambda x, y: x * y), talnalisti)
print(f"Multiplying all of {talnalisti}, we get {product_}")
Output :
Multiplying all of [20, 35, 19, 34, 10, 15, 33, 60, 22, 35, 12, 66, 14, 48, 5, 59, 9, 5, 8, 22, 65, 32, 17, 24, 58, 47, 8, 14, 24, 44, 62, 58, 29, 9, 53, 59, 6, 35, 49, 29, 51, 6, 15, 37, 43, 31, 64, 65, 35, 9], we get 9141144262078455405304024709785603282981464013901848903680000000000000

You can keep track of the product of each number you add to the list.
import random
talnalisti = []
result = 1
for x in range(50):
tala = random.randint(5, 70)
result *= tala
talnalisti.append(tala)
print(talnalisti)
print("Product of list is ", result)
print("Stærsta talan er", max(talnalisti))
print("Minsta talan er", min(talnalisti))

Related

How to create a list with a random number of random integers in Python

I want to create a list that is a random length of randomly chosen integers. What I have so far is:
a = [random.randint, random.randint, random.randint] and it goes on, but I want it so that it isn't however many times I typed "random.randint", but it uses the random function to generate a random number of random integers.
that's what I would do:
import random
a = random.randint(0,100)
b = []
for i in range(0,a):
b.append(random.randint(0,100))
Use the below code, bunch of random.randint and on single random.sample:
import random
l=[random.randint(0,100) for i in range(100)]
print(random.sample(l,random.randint(0,100)))
Output:
[27, 44, 80, 95, 54, 41, 52, 26, 21, 26, 91, 92, 10, 85, 13, 62, 30, 45, 0, 24, 58, 11, 95, 17, 0, 29, 37, 66]
Numpy if you're planning on a large scale (it will be faster than list comprehension)
import numpy as np
your_list = list(np.random.randint(0,100,n)) # n is the list size.
You can do away with list if you only need an iterable.
i think that will solve your problem choice
s = [random.randint (0, 100) for i in range(5)]
print (s)

Select elements in such a way that most of the elements are in the beginning of a list

I have a list of values and I want to select n values in such a way that most of the elements come from the beginning of the list and diminish as it goes further in the list (as shown in the link below).
np.random.seed(0)
a = pd.Series(range(100))
np.random.shuffle(a)
a.values
array([26, 86, 2, 55, 75, 93, 16, 73, 54, 95, 53, 92, 78, 13, 7, 30, 22,
24, 33, 8, 43, 62, 3, 71, 45, 48, 6, 99, 82, 76, 60, 80, 90, 68,
51, 27, 18, 56, 63, 74, 1, 61, 42, 41, 4, 15, 17, 40, 38, 5, 91,
59, 0, 34, 28, 50, 11, 35, 23, 52, 10, 31, 66, 57, 79, 85, 32, 84,
14, 89, 19, 29, 49, 97, 98, 69, 20, 94, 72, 77, 25, 37, 81, 46, 39,
65, 58, 12, 88, 70, 87, 36, 21, 83, 9, 96, 67, 64, 47, 44])
what is the good way to select those numbers?
http://www.bydatabedriven.com/wp-content/uploads/2012/12/Screen-Shot-2012-12-03-at-8.12.36-PM.png
As an example if n = 10, then the returned values may be (more numbers picked from the begining of the list as compared to those values which are to the end of the list) :
26, 2, 16, 92, 8, 45, 61, 99, 94 39
You can use np.random.choice and pass appropriately-shaped weights, either directly or using pd.Series.sample since you're using pandas. For example:
In [59]: s = pd.Series(range(100))
In [60]: chosen = s.sample(10**6, replace=True, weights=1.0/(1+np.arange(len(s)))) #typecast the weight to float
In [61]: chosen.hist(bins=50).get_figure().savefig("out.png")
gives me
You can tweak the weights function to your heart's content. Here I used basically 1/i, so that the 4th element is 4 times less likely to be selected than the first. You could take that expression to some power, with **2 making the 4th element 16 times less likely to be selected, or **0.5 making the 4th element half as likely to be selected as the first. Entirely up to you to find a behaviour you're happy with.
Also note that here I'm using replace=True, because I wanted to select a large number of values to make the plot look better. If you don't want the same element to be selected twice, use replace=False.
Solving by Re-inventing the Wheel
Here is how you do it from the first principles.
random.random() returns a random number between 0 and 1. This means that the expression random.random() < x becomes true less frequently as x becomes closer to 0.
For each element in the array, say array[i], let us define the odds of the element getting picked as
odds_pick(i) = (1 - i / len(array)) * DAMP.
Here, DAMP is a number between 0 and 1, which is used to diminish the odds of a number being picked. Thus,
when i = 0 (the first element), the odds of the element being picked are just = DAMP.
For the last element, it's DAMP / len(array).
For others, the odds are between these extremes, and they diminish as i gets larger.
Finally, to get this appropriate sample, iterate over the array, and check if random.random() < odds_pick(i). If so, pick the element.
Because of how we have defined odds_pick(i), it will become more and more close to 0 as i increases, and thus random.random() < odds_pick(i) will be less and less true towards the end. Ultimately, this means we end up picking elements more frequently from the front than from the end.
Code:
import random
def sample_with_bias(arr, n, damping_factor=.3):
res = []
indexes_picked = []
n_picked = 0
while n_picked < n:
for i, x in enumerate(arr):
odds_pick = damping_factor * (1 - i * 1. / len(arr))
if i not in indexes_picked and random.random() < odds_pick:
print(odds_pick)
n_picked += 1
indexes_picked.append(i)
res.append(x)
return res
Note that there are multiple pass over the array to cover the corner case where n unique elements could not be sampled in a single pass.
Let's run some experiments:
def run_experiment(arr, damping_factor, num_pick=10, num_runs=100):
all_samples = []
for i in range(num_runs):
all_samples.extend(sample_with_bias(arr, num_pick, damping_factor=damping_factor))
dist = Counter(all_samples)
dist = sorted(list(dist.items()), key=lambda k: k[0])
k, v = zip(*dist)
plt.bar(k, v)
plt.title("Damping Factor = {0}".format(damping_factor))
plt.show()
and
for df in [0.10, 0.50, 0.99]:
np.random.seed(0)
a = pd.Series(range(100))
run_experiment(a, damping_factor=df)
Results
For lots of damping, almost uniform with still a bias for the elements in the beginning:
Let's see what happens when we decrease the damping:
With almost no damping, only the elements in the front are picked:

How can I sort through a range in a csv file in python?

My problem: I have a csv file that has data that goes between 90 to 3 meters deep, and that data will go back and forth like so. I am using the newest python.
ex. (depth) 88, 77, 50, 20, 5, 90, 76, 54, 34, 15, 8, 4, 81, 74, 62,51, 49, 30, 22, 10, 8... and so on. It keeps goes from 90 to 3, and back again.
What I want to do is to separate the data each time it goes between 90 and 3. Once it is separated I want to take the last and first values in that list.
Like so
ex. 88, 77, 50, 20, 5 (separate here), 90, 76, 54, 34, 15, 8, 4 (separate here) 81, 74, 62,51, 49, 30, 22, 10, 8 separate here)... and so on. It keeps goes from 90 to 3, and back again.
How do I go about doing this? Or how would I separate them into them into lists and then use data from each of them?
Here's the code I have so far:
import csv, numpy
from collections import defaultdict
columns = defaultdict(list) # each value in each column is appended to a list
with open('C:\\Users\\AdamStoer\\Documents\\practicedata.csv') as f:
reader = csv.DictReader(f,delimiter=',') # read rows into a dictionary format
for row in reader:
r = float(row['roll'])
p = float(row['pitch'])
if 0.21 <= p <= 0.31:
if -0.06 <= r <= 0.06:
columns['pitch'].append(row['pitch'])
columns['roll'].append(row['roll'])
columns['i_depth'].append(row['i_depth'])
columns['irrad2'].append(row['sci_ocr504i_irrad2'])
print ('Pitch:')
print (columns['pitch'])
print ('Roll:')
print (columns['roll'])
print ('Depth')
print (columns['i_depth'])
print ("Irrandiance(2):")
print (columns['irrad2'])
irradlst = columns['irrad2']
irradfirst = irradlst[0]
irradlast = irradlst[-1]
depthlst = columns['i_depth']
depthfirst = depthlst[0]
depthlast = depthlst[-1]
print ("\nDepth 1 is " + depthfirst + " and " + "Depth 2 is " + depthlast)
print ("\nIrradiance 1 is " + irradfirst + " and " + "Irradiance 2 is " + irradlast)
#Find the Volume Attenuation Coefficient
#irranddiv = deepest/shallowest
irraddiv = float(irradfirst)/float(irradlast)
#depthdif = deepest-shallowest
depthdif = float(depthfirst) - float(depthlast)
#Find Log of irraddiv
irradlog = numpy.log(irraddiv)
#Find K
K = irradlog/(-depthdif)
print("\nAttenuation Coefficient")
print (K)
well your code is a little complicated and i don't know numpy, anyway this is a solution i came up with for separating range of number:
l = [88, 77, 50, 20, 5, 90, 76, 54, 34, 15, 8, 4, 81, 74, 62,51, 49, 30, 22, 10, 8,65]
group =0 #since were using dictionaries i use group number as dictionary KEY to distinguish each group of number between 3 to 90
temp = [] # this is a list that we keep temporary group of our number ranged between 3 to 90
splited_list = {} #this is a dictionary that we keep our final result in side it
lengh = len(l) #this is a lengh of our list of numbers
for i in range(lengh): # we run our code for each number inside our list of number
if not i == lengh-1: # at this line we check if our number is not the last number in list , because in next line we check our number with the number that comes after our current number and if it's the last number we get "IndexError: list index out of range" error at next line
if l[i] > l[i+1]: # since our range is between 3 to 90 , so if our current number is bigger than next number, for sure it is bigger than 3, so it is between 3 to 90 and we can add it to our current group of number
temp.append(l[i])
else: #if it is not bigger than the next number it is our last number in our current group of number in range of 90 to 3 so we add it to our temp
temp.append(l[i])
group +=1
splited_list.update({str(group):temp})
temp = []
else: # when we reach this line it means that we get to the last number in ourlist , since there is no next number , we check it with previous number , if its bigger it is not belong to current group of number between 3 to 90 and if it's smaller it is belong to the current group of number
if l[i] < l[-2]:
temp.append(l[i])
group +=1
splited_list.update({str(group):temp})
break
else:
group +=1
splited_list.update({str(group):[l[i]]})
break
it separate range 90 to 3 as you wanted ,it gives this output:
>>> splited_list
{'2': [90, 76, 54, 34, 15, 8, 4], '1': [88, 77, 50, 20, 5], '4': [65], '3': [81, 74, 62, 51, 49, 30, 22, 10, 8]}
This task is straight forward with numpy.diff() and numpy.where() as:
Code:
import numpy as np
def split_at_mins(a_list):
end_points = list(1 + np.where(0 < np.diff(a_list))[0])
return [a_list[i:j] for i, j in
zip([0] + end_points, end_points + [len(a_list)])]
Test Code:
test_data = (
88, 77, 50, 20, 5,
90, 76, 54, 34, 15, 8, 4,
81, 74, 62, 51, 49, 30, 22, 10, 8
)
print('\n'.join(str(d) for d in split_at_mins(test_data)))
print('\n'.join('%s %s' % (d[0], d[-1]) for d in split_at_mins(depth)))
Produces:
(88, 77, 50, 20, 5)
(90, 76, 54, 34, 15, 8, 4)
(81, 74, 62, 51, 49, 30, 22, 10, 8)
88 5
90 4
81 8

Is it possible to randomly *remove* a percentage/number of items from a list & then *append* them to another list?

I am new to python and programming, so apologies in advance. I know of remove(), append(), len(), and rand.rang (or whatever it is), and I believe I would need those tools, but it's not clear to me how to code it.
What I would like to do is, while looping or otherwise accessing List_A, randomly select an index within List_A, remove the selected_index from List_A, and then append() the selected_index to List_B.
I would like to randomly remove only up to a certain percentage (or real number if this is impossible) of items from List A.
Any ideas?? Is what I'm describing possible?
If you don't care about the order of the input list, I'd shuffle it, then remove n items from that list, adding those to the other list:
from random import shuffle
def remove_percentage(list_a, percentage):
shuffle(list_a)
count = int(len(list_a) * percentage)
if not count: return [] # edge case, no elements removed
list_a[-count:], list_b = [], list_a[-count:]
return list_b
where percentage is a float value between 0.0 and 1.0.
Demo:
>>> list_a = range(100)
>>> list_b = remove_percentage(list_a, 0.25)
>>> len(list_a), len(list_b)
(75, 25)
>>> list_b
[1, 94, 13, 81, 23, 84, 41, 92, 74, 82, 42, 28, 75, 33, 35, 62, 2, 58, 90, 52, 96, 68, 72, 73, 47]
If you can find a random index i of some element in listA, then you can easily move it from A to B using:
listB.append(listA.pop(i))
>>> lis = range(100)
>>> per = .30
>>> no_of_items = int( len(lis) * per) #number of items in 30 percent
>>> lis_b = []
>>> for _ in xrange(no_of_items):
ind = random.randint(0,len(lis)-1) #selects a random index value
lis_b.append(lis.pop(ind)) #pop the item at that index and append to lis_b
...
>>> lis_b
[73, 32, 82, 68, 90, 19, 3, 49, 21, 17, 30, 75, 1, 31, 80, 48, 38, 18, 99, 98, 4, 20, 33, 29, 66, 41, 64, 26, 77, 95]
1) Calculate how many elements you want to remove, call it k.
2) random.randrange(len(listA)) will return a random number between 0 and len(listA)-1 inclusive, e.g. a random index you can use in listA.
3) Grab the element at that index, remove it from listA, append it to listB.
4) Repeat until you have removed k elements.

Trying to write an Eratosthenes Sieve in Python. Is this correct and how can I make it faster? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Fastest way to list all primes below N in python
I have not been doing programming for very long, and I'm just doing this for fun, and I don't know much advanced Python, but...
I wrote this, and I wanted to know whether it is actually an Eratosthenes Sieve program, and if it is, how could I make it faster. I don't really want someone to post a program that is a solution, but more tell me how I could adapt mine.
def eratSieve(n):
all = []
for a in range(2, n+1):
all.append(a)
for b in all:
for i in range(2,int(round(len(all)/b))):
while i*b in all:
all.remove(i*b)
i+=1
return all
Thanks for your help.
BTW - It's in Python 2.7
It does not work right.
The main problem is that you loop on all the value in all and in the while you remove some element from all.
This way some value in all are not considered, so the function does not remove all the non-prime numbers
Try to execute it for n=100 and the result you get is
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99
while it should be
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97
(from http://en.wikipedia.org/wiki/Prime_number)
Also, the range of the second for is wrong, since you consider the lenght of the list, not the current value of b and so you check for multiple of 2 only in the first 50 values, the multiple of 3 in the first 17, 5 in the first 9 and so on. From b = 13 you never enter in the inner for, since int(round(len(all)/b)) = 1 and so you have something like for i in range(2,1)
I agree with Gianluca, and I have a possible solution: keep your main array (all) as bools and mark non-primes, but don't remove them. It might also be faster, because you don't change list size.
Minor thing: you can just write all = range(2, n+1) in the beginning if you want to keep it as ints.
Your method produces incorrect results. The error lies in the for i loop. Here it is, adjusted, and with a test:
known_primes = [
2,3,5,7,11,13,17,19,23,29,
31,37,41,43,47,53,59,61,67,71,
73,79,83,89,97,101,103,107,109,113,
127,131,137,139,149,151,157,163,167,173,
179,181,191,193,197,199,211,223,227,229,
233,239,241,251,257,263,269,271,277,281,
283,293,307,311,313,317,331,337,347,349,
353,359,367,373,379,383,389,397,401,409,
419,421,431,433,439,443,449,457,461,463,
467,479,487,491,499,503,509,521,523,541,
547,557,563,569,571,577,587,593,599,601,
607,613,617,619,631,641,643,647,653,659,
661,673,677,683,691,701,709,719,727,733,
739,743,751,757,761,769,773,787,797,809,
811,821,823,827,829,839,853,857,859,863,
877,881,883,887,907,911,919,929,937,941,
947,953,967,971,977,983,991,997,1009,1013,
1019,1021,1031,1033,1039,1049,1051,1061,1063,1069,
1087,1091,1093,1097,1103,1109,1117,1123,1129,1151,
1153,1163,1171,1181,1187,1193,1201,1213,1217,1223,
1229,1231,1237,1249,1259,1277,1279,1283,1289,1291,
1297,1301,1303,1307,1319,1321,1327,1361,1367,1373,
1381,1399,1409,1423,1427,1429,1433,1439,1447,1451,
1453,1459,1471,1481,1483,1487,1489,1493,1499]
def eratSieve(n):
all = []
for a in range(2, n+1):
all.append(a)
for b in all:
for i in all[all.index(b):]:
while i*b in all:
all.remove(i*b)
i+=1
return all
for N in range(1500):
for n in eratSieve(N):
if n not in known_primes:
print N,n
def primes(N):
primes = [x for x in (2, 3, 5, 7, 11, 13) if x < N]
if N < 17: return primes
candidators = [x for x in xrange((N - 2) | 1, 15, -2)
if x % 3 and x % 5 and x % 7 and x % 11 and x % 13]
top = int(N ** 0.5)
while (top + 1) * (top + 1) <= N: top += 1
while True:
p = candidators.pop()
primes.append(p)
if p > top: break
candidators = filter(p.__rmod__, candidators)
candidators.reverse()
primes.extend(candidators)
return primes
I think this code would work faster...

Categories

Resources