Writing if-else loop for a list in Python - python

I have a list A. I want to generate a new list Anew with if-else loop such that an average is taken whenever there are two values. For example, A[2][0][0]and A[2][1][0] exist hence, average is taken, A[3][1][0] doesn't exist and no average is possible for this position in Anew.
A=[[[0.369577823]],
[[0.987884443]],
[[1.244425627], [1.058887146]],
[[3.707809378]],
[[0.476881021]],
[[0.304499065], [1.037728999]],
[[3.073758392], [5.032947535]]]
Anew=[[[A[0][0][0]],
[A[1][0][0]],
[(A[2][0][0]+A[2][1][0])/2],
[A[3][0][0]],
[A[4][0][0]],
[(A[5][0][0]+A[5][1][0])/2],
[(A[6][0][0]+A[6][1][0])/2]]]
The desired output is
[[[0.369577823],
[0.987884443],
[1.1516563865],
[3.707809378],
[0.476881021],
[0.671114032],
[4.0533529635]]]

Try this.
A=[[[0.369577823]], [[0.987884443]], [[1.244425627], [1.058887146]], [[3.707809378]], [[0.476881021]], [[0.304499065], [1.037728999]],
[[3.073758392], [5.032947535]]]
s2 = [[]]
for a in A:
s = []
for i in a:
s.append(sum(i))
s2[0].append([sum(s)/len(s)])
print(s2)
OUTPUT
[[[0.369577823], [0.987884443], [1.1516563865], [3.707809378], [0.476881021], [0.671114032], [4.0533529635]]]

all_numbers=[[[0.369577823]],
[[0.987884443]],
[[1.244425627], [1.058887146]],
[[3.707809378]],
[[0.476881021]],
[[0.304499065], [1.037728999]],
[[3.073758392], [5.032947535]]]
new_numbers = [[]]
for numbers in all_numbers:
if len(numbers) == 1:
new_numbers[0].append(numbers[0])
else:
new_add = 0
for number in numbers:
new_add += number[0]
new_add = new_add/len(numbers)
new_numbers[0].append([new_add])
print(new_numbers)
output
[[[0.369577823], [0.987884443], [1.1516563865], [3.707809378], [0.476881021], [0.671114032], [4.0533529635]]]

Related

Changing this Python program to have function def()

The following Python program flips a coin several times, then reports the longest series of heads and tails. I am trying to convert this program into a program that uses functions so it uses basically less code. I am very new to programming and my teacher requested this of us, but I have no idea how to do it. I know I'm supposed to have the function accept 2 parameters: a string or list, and a character to search for. The function should return, as the value of the function, an integer which is the longest sequence of that character in that string. The function shouldn't accept input or output from the user.
import random
print("This program flips a coin several times, \nthen reports the longest
series of heads and tails")
cointoss = int(input("Number of times to flip the coin: "))
varlist = []
i = 0
varstring = ' '
while i < cointoss:
r = random.choice('HT')
varlist.append(r)
varstring = varstring + r
i += 1
print(varstring)
print(varlist)
print("There's this many heads: ",varstring.count("H"))
print("There's this many tails: ",varstring.count("T"))
print("Processing input...")
i = 0
longest_h = 0
longest_t = 0
inarow = 0
prevIn = 0
while i < cointoss:
print(varlist[i])
if varlist[i] == 'H':
prevIn += 1
if prevIn > longest_h:
longest_h = prevIn
print("",longest_h,"")
inarow = 0
if varlist[i] == 'T':
inarow += 1
if inarow > longest_t:
longest_t = inarow
print("",longest_t,"")
prevIn = 0
i += 1
print ("The longest series of heads is: ",longest_h)
print ("The longest series of tails is: ",longest_t)
If this is asking too much, any explanatory help would be really nice instead. All I've got so far is:
def flip (a, b):
flipValue = random.randint
but it's barely anything.
import random
def Main():
numOfFlips=getFlips()
outcome=flipping(numOfFlips)
print(outcome)
def getFlips():
Flips=int(input("Enter number if flips:\n"))
return Flips
def flipping(numOfFlips):
longHeads=[]
longTails=[]
Tails=0
Heads=0
for flips in range(0,numOfFlips):
flipValue=random.randint(1,2)
print(flipValue)
if flipValue==1:
Tails+=1
longHeads.append(Heads) #recording value of Heads before resetting it
Heads=0
else:
Heads+=1
longTails.append(Tails)
Tails=0
longestHeads=max(longHeads) #chooses the greatest length from both lists
longestTails=max(longTails)
return "Longest heads:\t"+str(longestHeads)+"\nLongest tails:\t"+str(longestTails)
Main()
I did not quite understand how your code worked, so I made the code in functions that works just as well, there will probably be ways of improving my code alone but I have moved the code over to functions
First, you need a function that flips a coin x times. This would be one possible implementation, favoring random.choice over random.randint:
def flip(x):
result = []
for _ in range(x):
result.append(random.choice(("h", "t")))
return result
Of course, you could also pass from what exactly we are supposed to take a choice as a parameter.
Next, you need a function that finds the longest sequence of some value in some list:
def longest_series(some_value, some_list):
current, longest = 0, 0
for r in some_list:
if r == some_value:
current += 1
longest = max(current, longest)
else:
current = 0
return longest
And now you can call these in the right order:
# initialize the random number generator, so we get the same result
random.seed(5)
# toss a coin a hundred times
series = flip(100)
# count heads/tails
headflips = longest_series('h', series)
tailflips = longest_series('t', series)
# print the results
print("The longest series of heads is: " + str(headflips))
print("The longest series of tails is: " + str(tailflips))
Output:
>> The longest series of heads is: 8
>> The longest series of heads is: 5
edit: removed the flip implementation with yield, it made the code weird.
Counting the longest run
Let see what you have asked for
I'm supposed to have the function accept 2 parameters: a string or list,
or, generalizing just a bit, a sequence
and a character
again, we'd speak, generically, of an item
to search for. The function should return, as the value of the
function, an integer which is the longest sequence of that character
in that string.
My implementation of the function you are asking for, complete of doc
string, is
def longest_run(i, s):
'Counts the longest run of item "i" in sequence "s".'
c, m = 0, 0
for el in s:
if el==i:
c += 1
elif c:
m = m if m >= c else c
c = 0
return m
We initialize c (current run) and m (maximum run so far) to zero,
then we loop, looking at every element el of the argument sequence s.
The logic is straightforward but for elif c: whose block is executed at the end of a run (because c is greater than zero and logically True) but not when the previous item (not the current one) was not equal to i. The savings are small but are savings...
Flipping coins (and more...)
How can we simulate flipping n coins? We abstract the problem and recognize that flipping n coins corresponds to choosing from a collection of possible outcomes (for a coin, either head or tail) for n times.
As it happens, the random module of the standard library has the exact answer to this problem
In [52]: random.choices?
Signature: choices(population, weights=None, *, cum_weights=None, k=1)
Docstring:
Return a k sized list of population elements chosen with replacement.
If the relative weights or cumulative weights are not specified,
the selections are made with equal probability.
File: ~/lib/miniconda3/lib/python3.6/random.py
Type: method
Our implementation, aimed at hiding details, could be
def roll(n, l):
'''Rolls "n" times a dice/coin whose face values are listed in "l".
E.g., roll(2, range(1,21)) -> [12, 4] simulates rolling 2 icosahedron dices.
'''
from random import choices
return choices(l, k=n)
Putting this together
def longest_run(i, s):
'Counts the longest run of item "i" in sequence "s".'
c, m = 0, 0
for el in s:
if el==i:
c += 1
elif c:
m = m if m >= c else c
c = 0
return m
def roll(n, l):
'''Rolls "n" times a dice/coin whose face values are listed in "l".
E.g., roll(2, range(1,21)) -> [12, 4] simulates rolling 2 icosahedron dices.
'''
from random import choices
return choices(l, k=n)
N = 100 # n. of flipped coins
h_or_t = ['h', 't']
random_seq_of_h_or_t = flip(N, h_or_t)
max_h = longest_run('h', random_seq_of_h_or_t)
max_t = longest_run('t', random_seq_of_h_or_t)

Iterate through list and assign a value to the variable in Python

So i'm currently working on code, which solves simple differentials. For now my code looks something like that:
deff diff():
coeffs = []
#checking a rank of a function
lvl = int(raw_input("Tell me a rank of your function: "))
if lvl == 0:
print "\nIf the rank is 0, a differential of a function will always be 0"
#Asking user to write coefficients (like 4x^2 - he writes 4)
for i in range(0, lvl):
coeff = int(raw_input("Tell me a coefficient: "))
coeffs.append(coeff)
#Printing all coefficients
print "\nSo your coefficients are: "
for item in coeffs:
print item
And so what I want to do next? I have every coefficient in my coeffs[] list. So now I want to take every single one from there and assign it to a different variable, just to make use of it. And how can I do it? I suppose I will have to use loop, but I tried to do so for hours - nothing helped me. Sooo, how can I do this? It would be like : a=coeff[0], b = coeff[1], ..., x = coeff[lvl] .
Just access the coefficients directly from the list via their indices.
If you are wanting to use the values in a different context that entails making changes to the values but you want to keep the original list unchanged then copy the list to a new list,
import copy
mutableCoeffs = copy.copy(coeffs)
You do not need new variables.
You already have all you need to compute the coefficients for the derivative function.
print "Coefficients for the derivative:"
l = len(coeffs) -1
for item in coeffs[:-1]:
print l * item
l -=1
Or if you want to put them in a new list :
deriv_coeffs = []
l = len(coeffs) -1
for item in coeffs[:-1]:
deriv_coeffs.append(l * item)
l -=1
I guess from there you want to differenciate no? So you just assign the cofficient times it rank to the index-1?
deff diff():
coeffs = []
#checking a rank of a function
lvl = int(raw_input("Tell me a rank of your function: "))
if lvl == 0:
print "\nIf the rank is 0, a differential of a function will always be 0"
#Asking user to write coefficients (like 4x^2 - he writes 4)
for i in range(0, lvl):
coeff = int(raw_input("Tell me a coefficient: "))
coeffs.append(coeff)
#Printing all coefficients
print "\nSo your coefficients are: "
for item in coeffs:
print item
answer_coeff = [0]*(lvl-1)
for i in range(0,lvl-1):
answer_coeff[i] = coeff[i+1]*(i+1)
print "The derivative is:"
string_answer = "%d" % answer_coeff[0]
for i in range(1,lvl-1):
string_answer = string_answer + (" + %d * X^%d" % (answer_coeff[i], i))
print string_answer
If you REALLY want to assign a list to variables you could do so by accessing the globals() dict. For example:
for j in len(coeffs):
globals()["elm{0}".format(j)] = coeffs[j]
Then you'll have your coefficients in the global variables elm0, elm1 and so on.
Please note that this is most probably not what you really want (but only what you asked for).

maximum value of a unique string in a list

Hi I'm trying to make a list of the maximum value of a unique string within a list.
example:
a = ['DS10.json', 'DS11.json', 'DT4.json', 'DT5.json', 'DT6.json', 'CJ6.json', 'CJ7.json']
should return me a list of the following:
['DS11.json', 'DT6.json', 'CJ7.json']
I have tried the following code:
def j(l):
p = []
for i in l:
digcode = i.split('.')[0]
if any(s.startswith(digcode[:2]) for s in p): #there exists prefex in list
if digcode[2:] > p[[n for n, l in enumerate(p) if l.startswith(digcode[:2])][0]][2:]:
p.pop([n for n, l in enumerate(p) if l.startswith(digcode[:2])][0])
p.append(digcode)
else:
pass
else:
p.append(digcode)
return p
But when I apply it to a larger sample it does not do an accurate job
>>> o = ['AS6.json', 'AS7.json', 'AS8.json', 'AS9.json', 'BS1.json', 'BS2.json', 'BS3.json', 'BS4.json', 'BS5.json', 'CS1.json', 'CS2.json', 'CS3.json', 'CS4.json', 'CS5.json', 'CS6.json', 'DS10.json', 'DS11.json', 'DS4.json', 'DS5.json', 'DS6.json', 'DS7.json', 'DS8.json', 'DS9.json', 'ES4.json', 'ES5.json', 'ES6.json', 'FS5.json', 'FS6.json', 'FS7.json', 'FS8.json', 'MS4.json', 'MS5.json', 'MS6.json', 'MS7.json', 'MS8.json', 'MS9.json', 'NR1.json', 'NR2.json', 'NR3.json', 'NR4.json', 'NR5.json', 'NR6.json', 'NR7.json', 'NR8.json', 'VR1.json', 'VR2.json', 'VR3.json', 'VR4.json', 'VR5.json', 'VR6.json', 'VR7.json', 'VR8.json', 'XS11.json', 'XS9.json']
>>> j(o)
['AS9', 'BS5', 'CS6', 'DS9', 'ES6', 'FS8', 'MS9', 'NR8', 'VR8', 'XS9']
which is incorrect as there is a XS11 and DS11 as an example.
I would appreciate if someone could help me rectify my problem or perhaps find a simpler solution to my problem. Thank you
You are making string comparisons; '9' is greater than '11' because the character '9' comes later in the alphabet. You'll have to convert those to integers first.
I'd use a dictionary to map prefixes to the maximum number:
def find_latest(lst):
prefixes = {}
for entry in lst:
code, value = entry[:2], int(entry.partition('.')[0][2:])
if value > prefixes.get(code, (float('-inf'), ''))[0]:
prefixes[code] = (value, entry)
return [entry for value, entry in prefixes.values()]
This is far more efficient as it doesn't loop over your whole input list each time; you are processing the list N^2 times (add one element and you are adding N tests to work through); it processes your list in N steps instead. So instead of 100 tests for 10 elements, this just executes 10 tests.
Demo:
>>> sample = ['AS6.json', 'AS7.json', 'AS8.json', 'AS9.json', 'BS1.json', 'BS2.json', 'BS3.json', 'BS4.json', 'BS5.json', 'CS1.json', 'CS2.json', 'CS3.json', 'CS4.json', 'CS5.json', 'CS6.json', 'DS10.json', 'DS11.json', 'DS4.json', 'DS5.json', 'DS6.json', 'DS7.json', 'DS8.json', 'DS9.json', 'ES4.json', 'ES5.json', 'ES6.json', 'FS5.json', 'FS6.json', 'FS7.json', 'FS8.json', 'MS4.json', 'MS5.json', 'MS6.json', 'MS7.json', 'MS8.json', 'MS9.json', 'NR1.json', 'NR2.json', 'NR3.json', 'NR4.json', 'NR5.json', 'NR6.json', 'NR7.json', 'NR8.json', 'VR1.json', 'VR2.json', 'VR3.json', 'VR4.json', 'VR5.json', 'VR6.json', 'VR7.json', 'VR8.json', 'XS11.json', 'XS9.json']
>>> def find_latest(lst):
... prefixes = {}
... for entry in lst:
... code, value = entry[:2], int(entry.partition('.')[0][2:])
... if value > prefixes.get(code, (float('-inf'), ''))[0]:
... prefixes[code] = (value, entry)
... return [entry for value, entry in prefixes.values()]
...
>>> find_latest(sample)
['FS8.json', 'VR8.json', 'AS9.json', 'MS9.json', 'BS5.json', 'CS6.json', 'XS11.json', 'NR8.json', 'DS11.json', 'ES6.json']
It looks as though your digcode[2:] values are being compared lexicographically (dictionary order), rather than numerically.
So 9 is considered to be "larger than" 11, because in a list of words, a word that began with "9" would come after a word that began with "11".
For comparison purposes you should convert digcode[2:] to a number i.e. int(digcode[2:])
if digcode[2:] > p[[n for n, l in enumerate(p) if l.startswith(digcode[:2])][0]][2:]:
to
if int(digcode[2:]) > int(p[[n for n, l in enumerate(p) if l.startswith(digcode[:2])][0]][2:]):
This gives:
>>> j(o)
['AS9', 'BS5', 'CS6', 'DS11', 'ES6', 'FS8', 'MS9', 'NR8', 'VR8', 'XS11']

Python iterating - problems finding the product of digits in a string

Trying to iterate through a number string in python and print the product of the first 5 numbers,then the second 5, then the third 5, etc etc. Unfortunately, I just keep getting the product of the first five digits over and over. Eventually I'll append them to a list. Why is my code stuck?
edit: Original number is an integer so I have to make it a string
def product_of_digits(number):
d= str(number)
for integer in d:
s = 0
k = []
while s < (len(d)):
print (int(d[s])*int(d[s+1])*int(d[s+2])*int(d[s+3])*int(d[s+4]))
s += 1
print (product_of_digits(a))
Let me list out the mistakes in the program.
You are iterating over d for nothing. You don't need that.
s += 1 is not part of the while loop. So, s will never get incremented, leading to infinite loop.
print (product_of_digits(a)) is inside the function itself, where a is not defined.
To find the product of all the consecutive 5 numbers, you cannot loop till the end of d. So, the loop should have been while s <= (len(d)-5):
You have initialized k, but used it nowhere.
So, the corrected program looks like this
def product_of_digits(number):
d, s = str(number), 0
while s <= (len(d)-5):
print(int(d[s]) * int(d[s+1]) * int(d[s+2]) * int(d[s+3]) * int(d[s+4]))
s += 1
product_of_digits(123456)
Output
120
720
You can also use a for loop, like this
def product_of_digits(number):
d = str(number)
for s in range(len(d) - 4):
print(int(d[s]) * int(d[s+1]) * int(d[s+2]) * int(d[s+3]) * int(d[s+4]))
There are a few problems with your code:
1) Your s+=1 indentation is incorrect
2) It should be s+=5 instead (assuming you want products of 1-5, 6-10, 11-15 and so on otherwise s+=1 is fine)
def product_of_digits(number):
d = str(number)
s = 0
while s < (len(d)-5):
print (int(d[s])*int(d[s+1])*int(d[s+2])*int(d[s+3])*int(d[s+4]))
s += 5 (see point 2)
print (product_of_digits(124345565534))
numpy.product([int(i) for i in str(s)])
where s is the number.

Returning multiple integers as separate variables

I am trying to make a program that grabs 5 integers from the user, and then finds the average of them. I have it set up to take in the 5 numbers, but how do I return them all as separate variables so I can use them later on? Thanks!
def main():
x = 0
testScoreNumber = 1
while x < 5:
getNumber_0_100(testScoreNumber)
x += 1
testScoreNumber += 1
calcAverage(score1, score2, score3, score4, score5)
print(calculatedAverage)
def getNumber_0_100(testnumber):
test = int(input("Enter test score " + str(testnumber) + ":"))
testcount = 0
while testcount < 1:
test = int(input("Enter test score " + str(testnumber) + ":"))
if test > 0 or test < 100:
testcount += 1
return test
^Here is the problem, the everytime this function runs, I want it to return a different value to a different variable. Ex. test1, test2, test3.
def calcAverage(_score1,_score2,_score3,_score4,_score5):
total = _score1 + _score2 + _score3 + _score4 + _score5
calculatedAverage = total/5
return calculatedAverage
You need to store the result somewhere. It is usually (always?) a bad idea to dynamically create variable names (although it is possible using globals). The typical place to store the results is in a list or a dictionary -- in this case, I'd use a list.
change this portion of the code:
x = 0
testScoreNumber = 1
while x < 5:
getNumber_0_100(testScoreNumber)
x += 1
testScoreNumber += 1
to:
results = []
for x in range(5):
results.append( getNumber_0_100(x+1) )
which can be condensed even further:
results = [ getNumber_0_100(x+1) for x in range(5) ]
You can then pass that results list to your next function:
avg = get_ave(results[0],results[1],...)
print(avg)
Or, you can use the unpacking operator for shorthand:
avg = get_ave(*results)
print(avg)
It isn't the responsibility of the returning function to say what the caller does with its return value. In your case, it would be simple to let main have a list where it adds the return values. You could do this:
scores = []
for i in range(5):
scores.append(getNumber_0_100(i))
calcAverage(*scores)
Note that *scores is to pass a list as arguments to your calcAverage function. It's probably better to have calculateAverage be a general function which takes a list of values and calculates their average (i.e. doesn't just work on five numbers):
def calcAverage(numbers):
return sum(numbers) / len(numbers)
Then you'd call it with just calcAverage(scores)
A more Pythonic way to write the first part might be scores = [getNumber_0_100(i) for i in range(5)]
Python allows you to return a tuple, and you can unroll this tuple when you receive the return values. For example:
def return_multiple():
# do something to calculate test1, test2, and test3
return (test1, test2, test3)
val1, val2, val3 = return_multiple()
The limitation here though is that you need to know how many variables you're returning. If the number of inputs is variable, you're better off using lists.

Categories