I'm trying to plot the output of my function into a list so I can plot it as a graph. My code so far is
t = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
def anninos():
for time in t:
tfac = math.factorial(time)
print(tfac)
anninos()
The output I get is
1
2
6
24
120
720
5040
40320
362880
3628800
but the output I want is
[1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800]
What code do I need to add to get this?
You could use a list comprehension or map() to construct a list:
>>> import math
>>> t = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> [math.factorial(time) for time in t]
[1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800]
>>> list(map(math.factorial, t))
[1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800]
You could then return the list from your function or print it.
You could use yield instead of print and do print(list(anninos())) instead of anninos(). You could also construct a list and append to it:
def anninos():
result = []
for time in t:
result.append(math.factorial(time))
print(result)
Whenever you have a loop that just creates a list of the same things, you can use a list comprehension:
def anninos():
print([math.factorial(time) for time in t])
You need use yield or not use funtion. You don't even use the return from a function - why do you use function?:
import math
t = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
def anninos(values_list):
for time in values_list:
yield math.factorial(time)
print list(anninos(t))
t = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
def anninos():
out = []
for time in t:
tfac = math.factorial(time)
out.append(tfac)
print(out)
anninos()
Related
I believe this is an easy problem to solve. I have searched and found a few similar answers but not an efficient way to exactly what I want to achieve.
Assuming the following list:
x = [6, 7, 8]
I want to create a new list by repeating each number k times. Assuming k=3, the result should be:
xr = [6, 6, 6, 7, 7, 7, 8, 8, 8]
I was able to accomplish this using nest loops, which I believe is very inefficient:
xr = []
for num in x: # for each number in the list
for t in range(3): # repeat 3 times
xx2.append(num)
I also tried:
[list(itertools.repeat(x[i], 3)) for i in range(len(x))]
but I get:
[[6, 6, 6], [7, 7, 7], [8, 8, 8]]
Is there a more efficient direct method to accomplish this?
You can use list comprehension:
x = [6, 7, 8]
k = 3
out = [v for v in x for _ in range(k)]
print(out)
Prints:
[6, 6, 6, 7, 7, 7, 8, 8, 8]
def repeat_k(l,k):
lo = []
for x in l:
for i in range(k):
lo.append(x)
return lo
print (repeat_k([1,2,3],5))
Output:
[1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3]
With list comprehension:
def repeat_k(l,k):
return [ x for x in l for i in range(k) ]
print (repeat_k([1,2,3],5))
Output:
[1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3]
Another possibility:
>>> x = [6, 7, 8]
>>> k = 3
>>> l = []
>>> for item in x:
... l += k * [item]
...
>>> l
[6, 6, 6, 7, 7, 7, 8, 8, 8]
You can create a convenient function:
def repeat(it, n):
for elem in it: yield from [elem] * n
Use it like:
>>> list(repeat(x, n=3))
[6, 6, 6, 7, 7, 7, 8, 8, 8]
Thanks, everyone for the answers.
It seems there is an easier and more direct way to solve this using Numpy.
np.repeat(x, 3).tolist()
prints exactly what I needed:
[6, 6, 6, 7, 7, 7, 8, 8, 8]
import itertools
x=[4,5,6]
k=3
res = list(itertools.chain.from_iterable(itertools.repeat(i, K) for i in test_list))
print (res)
It can also be solved using python inbuilt functions of itertools library. The repeat function does the task of repetition and grouping into a list is done by the from_iterable function.
What I am doing is creating a function that returns a list containing every number in a list of bases raised to every number in a list of powers. So, using a nested for loop I wrote two different ways:
First:
def exponents(bases, powers):
lst = []
for p in powers:
for b in bases:
lst.append(b ** p)
return lst
print(exponents([2, 3, 4], [1, 2, 3]))
This prints:
[2, 3, 4, 4, 9, 16, 8, 27, 64]
These values are wrong.
Second:
def exponents(bases, powers):
lst = []
for b in bases:
for p in powers:
lst.append(b ** p)
return lst
print(exponents([2, 3, 4], [1, 2, 3]))
This prints:
[2, 4, 8, 3, 9, 27, 4, 16, 64]
These are the correct values.
Why do these two very similar functions give different values? Is it related to floating point error?
Both functions are correct. You changed the order in which you compute the results.
Rearrange the output to a tabular format:
[2, 3, 4,
4, 9, 16,
8, 27, 64]
vs
[2, 4, 8,
3, 9, 27,
4, 16, 64]
These are the same values, but with rows and columns switched ... just as you specified in your code when you switch the computation order.
Your first example expands to:
2**1
3**1
4**1
2**2
3**2
4**2
2**3
3**3
4**3
Because for each p, loop through b
That computes to [2, 3, 4, 4, 9, 16, 8, 27, 64]
Your second example expands to:
2**1
2**2
2**3
3**1
3**2
3**3
4**1
4**2
4**3
Because you want for each b, loop through p
This computes to [2, 4, 8, 3, 9, 27, 4, 16, 64]
The values are correct--the order is different based on the order of looping that you desire
def list_move_back(new_value, value_list):
for i in reversed(value_list):
if value_list.index(i) != len(value_list)-1:
value_list[value_list.index(i)+1] = i
value_list[0] = new_value
return value_list
I want to get the following result:
list_example = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
list_example = list_move_back(12, list_example]
print(list_example)
>>>[12, 1, 2, 3, 4, 5, 6, 7, 8, 9]
It works if I run the function two times:
list_example = list_move_back(12, list_example]
print(list_example)
>>>[12, 12, 1, 2, 3, 4, 5, 6, 7, 8]
but if I want to run it a third time, the result looks like that:
list_example = list_move_back(12, list_example]
print(list_example)
>>>[12, 12, 1, 1, 3, 4, 5, 6, 7, 8]
The first 1 should be a 12. I have no idea why it doesn't work.
Just use list slicing:
def list_move_back(new_value, list_of_values):
return [new_value] + list_of_values[:-1]
Explanation: list_of_values[:-1] returns all the elements except for the last. By appending it to the new value, you get the wanted result. This answer has a pretty cool explanation of how list slicing works.
Also, if for some reason you'd like the "verbose" way to do this (maybe for an exercise or whatever), here's a way to go about it:
def list_move_back(new_value, list_of_values):
for i in range(len(list_of_values)-1, 0, -1):
list_of_values[i] = list_of_values[i-1]
list_of_values[0] = new_value
return list_of_values
I'd recommend list slicing over this method 9/10 times but again, I'm just leaving this here because there might be a case where someone wants to do this as some sort of mental exercise for indexing.
If you need the list to change in place, you can use the list methods .pop() to remove the last item and .insert(0,value) to add an item to the front:
>>> L = list(range(1,11))
>>> L
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> id(L)
1772071032392
>>> L.pop();L.insert(0,12)
10
>>> L
[12, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> id(L) # same list id, modified in place...
1772071032392
I am trying to come up with a function to split the length of a list evenly depending on it's original length.
So for example if I have a dataset returned that is 2000 I would like to split it into 4. Whereas if the dataset is 1500 split it into 3.
Then to call the function:
Thread_A_DATA, Thread_B_DATA = split_list( SQL_RETURN )
I would like to do something like the following:
if len(dataset) <= 1000:
# Split in 2
a, b = split_list(dataset, 2)
if len(dataset) > 1000 or len(dataset) <= 1500:
# Split in 3
a, b, c = split_list(dataset, 3)
# etc etc...
I've managed to split a dataset in half using this code found previously on stackoverflow:
def split_list( a_list ):
half = len( a_list ) / 2
return a_list[:half], a_list[half:]
But I can't work it out with 3,4 or 5 splits!
If anyone can help that would be great.
Thanks in advance.
As I understand the question, you don't want to split every 500 elements but instead split in 2 if there are less than 1000 elements, in 3 if less than 1500, 4 for 2000, etc. But if there are 1700 elements, you would split in 4 groups of 425 elements (that's what I understand by "split evenly").
So, here's my solution:
def split_list(a_list, number_of_splits):
step = len(a_list) / number_of_splits + (1 if len(a_list) % number_of_splits else 0)
return [a_list[i*step:(i+1)*step] for i in range(number_of_splits)]
l = [1, 8, 2, 3, 4, 5, 6, 7, 1, 5, 3, 1, 2, 5]
print l
print split_list(l, 3)
print split_list(l, 2)
Output
[1, 8, 2, 3, 4, 5, 6, 7, 1, 5, 3, 1, 2, 5]
[[1, 8, 2, 3, 4], [5, 6, 7, 1, 5], [3, 1, 2, 5]]
[[1, 8, 2, 3, 4, 5, 6], [7, 1, 5, 3, 1, 2, 5]]
edit: Python 3 version:
def split_list(a_list, number_of_splits):
step = len(a_list) // number_of_splits + (1 if len(a_list) % number_of_splits else 0)
return [a_list[i*step:(i+1)*step] for i in range(number_of_splits)]
l = [1, 8, 2, 3, 4, 5, 6, 7, 1, 5, 3, 1, 2, 5]
print(l)
print(split_list(l, 3))
print(split_list(l, 2))
Python 3
def splitList(L):
return[L[i:i+500] for i in range(0, len(L), 500)]
Python 2
def splitList(L):
return[L[i:i+500] for i in xrange(0, len(L), 500)]
def split_it(a_list,size_of_split):
return zip(*[iter(a_list)]*size_of_split)
is fun
print split_it(range(100),3) # splits it into groups of 3
unfortunatly this will truncate the end of the list if it does not divide evenly into split_size ... you can fix it like so
return zip(*[iter(a_list)]*size_of_split) + [tuple(a_list[-(len(a_list)%size_of_split):])]
if you wanted to cut it into 7 pieces say you can find the size of the split by
split_size = len(a_list) / num_splits
Python 2.7
>>> import math
>>> lst = range(35)
>>> t = 3 # how many items to be splited
>>> n = int(math.ceil(len(lst) / float(t)))
>>> res = [lst[i:i+n] for i in range(0, len(lst), n)]
>>> res
[[0, 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]]
How to generate a random (but unique and sorted) list of a fixed given length out of numbers of a given range in Python?
Something like that:
>>> list_length = 4
>>> values_range = [1, 30]
>>> random_list(list_length, values_range)
[1, 6, 17, 29]
>>> random_list(list_length, values_range)
[5, 6, 22, 24]
>>> random_list(3, [0, 11])
[0, 7, 10]
A random sample like this returns list of unique items of sequence. Don't confuse this with random integers in the range.
>>> import random
>>> random.sample(range(30), 4)
[3, 1, 21, 19]
A combination of random.randrange and list comprehension would work.
import random
[random.randrange(1, 10) for _ in range(0, 4)]
import random
def simplest(list_length):
core_items = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
random.shuffle(core_items)
return core_items[0:list_length]
def full_random(list_length):
core_items = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
result = []
for i in range(list_length):
result.append(random.choice(core_items))
return result
You can achieve this using random.choices() if you want to sample with replacement.
>>> import random
>>> random.choices(range(15), k=3)
[24, 29, 17]