Posts: 2
Threads: 1
Joined: Dec 2020
Hi,
I'm trying to put all answers of equations that I calculated into a list, and I want to refer to this list multiple times because the same equations repeat over and over again, is the function math.log the thing I want to use to make the code short?
Posts: 12,050
Threads: 487
Joined: Sep 2016
Please show your code (or runnable snippet) so we can suggest how to shorten.
I'm guessing that you might be able to save in sqlite database (built into python, easy to use)
Posts: 1,838
Threads: 2
Joined: Apr 2017
It isn't clear to me what logarithms have to do with your problem. Please show code and explain.
Posts: 6,826
Threads: 20
Joined: Feb 2020
Nope.
Output: >>> import math
>>> help(math.log)
Help on built-in function log in module math:
log(...)
log(x, [base=math.e])
Return the logarithm of x to the given base.
If the base not specified, returns the natural logarithm (base e) of x.
I need more information about what you are trying to do to have a chance at answering your question. Could you provide some code and a description please?
Posts: 2
Threads: 1
Joined: Dec 2020
Dec-03-2020, 08:31 PM
(This post was last modified: Dec-04-2020, 11:28 AM by Larz60+.
Edit Reason: fixed closing python tag
)
So for example i have an empty list (data), and I have a different list with some numbers(list_), I want to make math operations on them, there can be numbers that repeat in the list, so some operation have to be calculated multiple times, so instead of calculating multiple times, it can reach out to the list(data) that already has answers to operations calculated before.
For example:
1 2 3 4 |
data = []
list_ = [ 4 , 6 , 1 , 2 , 47 , 4 , 2 , 6 , 4 ]
for i in range ( len (list_ - 1 ):
data.append(list_[i] + list_[i + 1 ]
|
As you can see, some operations repeat multiple times, such as the first one(4+6), and the last one,(6+4). So instead of counting i again, you can go to the data list and get the value from the list, to make the code faster. Does anyone have a hint on how to do that and, is the function math.log even necessary in this program?
Thanks
Posts: 1,838
Threads: 2
Joined: Apr 2017
I don't see how logs are relevant at all. Where did you get the idea that they were?
Can't you use a set, so you only keep the unique values?
Posts: 1,583
Threads: 3
Joined: Mar 2020
Doesn't seem worth it for an inexpensive call like integer addition. But if you have expensive operations you could cache them with functools.cache (or functools.lru_cache if you don't have 3.9...)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
import functools
def expensive_function(n):
print ( f " Debug. Calling expensive_function with argument {n}" )
return n / 0.2385
@functools .lru_cache
def cached_function(n):
return expensive_function(n)
for i in range ( 3 ):
print (expensive_function( 4 ))
print ()
for i in range ( 3 ):
print (cached_function( 5 ))
|
Output: Debug. Calling expensive_function with argument 4
16.771488469601678
Debug. Calling expensive_function with argument 4
16.771488469601678
Debug. Calling expensive_function with argument 4
16.771488469601678
Debug. Calling expensive_function with argument 5
20.964360587002098
20.964360587002098
20.964360587002098
After the function is called with a particular argument, this value is returned from the cache on future calls with the same arguments. Don't use this if the output can change when the arguments don't (like a function that depends on a random number, or one that looks up data from a database...)
Posts: 6,826
Threads: 20
Joined: Feb 2020
Here's an example of saving previous values for calculating prime numbers.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
primes = [ 2 , 3 ]
def prime(i):
def notPrime(value):
sqrt = value * * 0.5
for p in primes:
if value % p = = 0 :
return True
if p > sqrt:
return False
count = 0
while len (primes) < = i:
value = primes[ - 1 ] + 2
while notPrime(value):
value + = 2
count + = 1
primes.append(value)
if count > 0 :
print ( f 'Calculated {count} new primes' )
return primes[i]
print (prime( 1 ))
print (prime( 5 ))
print (prime( 7 ))
print (prime( 10 ))
print (prime( 6 ))
print (primes)
|
Output: 3
Calculated 4 new primes
13
Calculated 2 new primes
19
Calculated 3 new primes
31
17
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31]
For this example a list works because the index is adequate for looking up the previously calculated value. You could also use something like this to get numbers from the Fibonacci sequence.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
fibonacci = [ 1 , 1 ]
def fib(i):
count = 0
while len (fibonacci) < = i:
fibonacci.append(fibonacci[ - 1 ] + fibonacci[ - 2 ])
count + = 1
if count > 0 :
print ( f 'Calculated {count} new values' )
return fibonacci[i]
print (fib( 1 ))
print (fib( 5 ))
print (fib( 7 ))
print (fib( 10 ))
print (fib( 6 ))
print (fibonacci)
|
Output: 1
Calculated 4 new values
8
Calculated 2 new values
21
Calculated 3 new values
89
13
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
Your problem is a bit trickier. An index will not work as a "key" to retrieve previously calculated values. You will probably use a dictionary. With a dictionary you'll need a key.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
results = {}
def addum(x):
key = str ( set (x))
result = results.get(key)
if result:
print ( f 'Reuse {x[0]}, {x[1]}' )
else :
result = sum (x)
results[key] = result
return result
numbers = [ 4 , 6 , 1 , 2 , 7 , 4 , 2 , 6 , 4 , 6 , 2 , 1 ]
print ([addum(x) for x in zip (numbers[: - 1 ], numbers[ 1 :])])
|
Output: Reuse 6, 4
Reuse 4, 6
Reuse 6, 2
Reuse 2, 1
[10, 7, 3, 9, 11, 6, 8, 10, 10, 8, 3]
Doing something like this you have to weigh the effort of calculating the value against the effort of generating keys and managing the dictionary.
This is a more substantial problem that reuses previous results many times.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
import random
solutions = {}
def sticks(bag, count):
if score : = solutions.get(( len (bag), count)):
return score
if count = = 1 :
score = ( sum (bag), [bag])
solutions[( len (bag), count)] = score
return score
best_score = 0
for i in range ( 1 , len (bag) - count + 1 ):
if count > 1 :
score, groups = sticks(bag[i:], count - 1 )
groups = [bag[:i]] + groups
score = min (score, sum (bag[:i]))
if score > best_score:
best_score = score
best = groups
solutions[( len (bag), count)] = (best_score, best)
return (best_score, best)
bag = list ( range ( 1 , 51 ))
random.shuffle(bag)
print (sticks(bag, 7 ))
|
Posts: 6,826
Threads: 20
Joined: Feb 2020
functools.cache is not going to know that expensive_function(6, 4) is the same as expensive_function(4, 6). But if this is an expensive function the order of the arguments is probably important.
Care must be taken if your cached function returns a mutable result. Just last week somebody was using functools to speed up their code and it led to unexpected results because a cached list was returned instead of generating a new list each time.
|