Random.randint on lists in Python - list

I want to create a list and fill it with 15 zeros, then I want to change the 0 to 1 in 5 random spots of the list, so it has 10 zeros and 5 ones, here is what I tried
import random, time
dasos = []
for i in range(1, 16):
dasos.append(0)
for k in range(1, 6):
dasos[random.randint(0, 15)] = 1
Sometimes I would get anywhere from 0 to 5 ones but I want exactly 5 ones,
if I add:
print(dasos)
...to see my list I get:
IndexError: list assignment index out of range

I think the best solution would be to use random.sample:
my_lst = [0 for _ in range(15)]
for i in random.sample(range(15), 5):
my_lst[i] = 1
You could also consider using random.shuffle and use the first 5 entries:
my_lst = [0 for _ in range(15)]
candidates = list(range(15))
random.shuffle(candidates)
for i in candidates[0:5]:
my_lst[i] = 1
TL;DR: Read the the Python random documentation, this can be done in multiple ways.

Related

How do I create randomized lists using a nested for loop

So I'm trying to make 2 lists with random variables compare to each other to find the probability of them being the same. What I've done is made 2 lists with random numbers using a for loop, but in order to find the probability I'm trying to create the lists within another for loop in order to make 10000 pairs of lists to compare but I can't get it to work.
import random
import collections
N= 10000
count = 0
playerPick=[]
randomPick=[]
for j in range (N):
for i in range(4):
playerPick.append(random.randrange(1,21))
print(playerPick)
for i in range(4):
randomPick.append(random.randrange(1,21))
print(randomPick)
if collections.Counter(playerPick) == collections.Counter(randomPick):
count+=1
probability = count/N
print("Probability of winning: ", probability)
The lists end up being super long but I just want them to be 4 long.
This may be a more efficient way to calculate the average match count.
import random
import collections
N = 10000 # main list length
L = 4 # each element is list of 4 elements
def getpct():
# create random list of lists
playerPick=[[random.randrange(1,21) for x in range(L)] for n in range(N)]
randomPick=[[random.randrange(1,21) for x in range(L)] for n in range(N)]
# create match list, 1=match else 0
matches = [1 if p==r else 0 for p,r in zip(playerPick,randomPick)]
return sum(matches)/N # percent matches
allpcts = [getpct() for r in range(1000)] # run test 1000 times
avgpct = sum(allpcts)/1000 # average percent
print(f'Avg Pct: {avgpct}%')
Output
Avg Pct: 6.2000000000000025e-06%

writing to columns in same row in csv file (python)

Im trying to write values to a csv file such that for every two iterations, the result is in the same row and then the next the values print to a new row. Any help would be greatly appreciated. Thank you!
This is what I have so far:
import csv
import math
savePath = '/home/dehaoliu/opencv_test/Engineering_drawings_outputs/'
with open(str(savePath) +'outputsTest.csv','w') as f1:
writer=csv.writer(f1, delimiter='\t',lineterminator='\n',)
temp = []
for k in range(0,2):
temp = []
for i in range(0,4):
a = 2 +i
b = 3+ i
list = [a,b]
temp.append(list)
writer.writerow(temp)
The result I am getting now is
[2 3][3 4][4 5][5 6]
[2 3][3 4][4 5][5 6]
But I would like to get this (without the brackets) where each number in a row is in a separate column:
2 3 3 4
4 5 5 6
Try the following:
import csv
import math
savePath = '/home/dehaoliu/opencv_test/Engineering_drawings_outputs/'
with open(str(savePath) +'outputsTest.csv','w') as f1:
writer=csv.writer(f1, delimiter='\t',lineterminator='\n',)
temp = [2, 3]
for i in range(2):
temp = [x + i for x in temp]
additional = [y+1 for y in temp]
writer.writerow(temp + additional)
temp = additional[:]
This should return:
# 2 3 3 4
# 4 5 5 6
You start with a temporary containing the numbers 2 and 3. Then, you loop from 0 to 2 (excluding). At every iteration, you increment the values of the temporary by the current index and subsequently create an additional list with these new values of your temporary list. Once that's done, you join the two lists together and write the result out to your file. At this point, you can set your temporary list to be equal to the values of the additional list, before moving on to the next iteration.
I hope this helps.
The way you present it you can do it with a simple seed and increment:
import csv
import os
save_path = "/home/dehaoliu/opencv_test/Engineering_drawings_outputs/"
with open(os.path.join(save_path, "outputsTest.csv"), "w") as f:
writer = csv.writer(f, delimiter="\t", lineterminator="\n")
temp = [2, 3, 3, 4] # init seed
increment = len(temp) // 2 # how many pairs we have, used to increase our seed each row
for _ in range(2): # how many rows do you need, any positive integer will do
writer.writerow(temp) # write the current value
temp = [x + increment for x in temp] # add 'increment' to the elements
Resulting in:
2 3 3 4
4 5 5 6
But if your seed is: temp = [2, 3, 3, 4, 4, 5] and you decide to generate 4 rows, it will still adapt:
2 3 3 4 4 5
5 6 6 7 7 8
8 9 9 10 10 11
11 12 12 13 13 14

How many times a number in list 1 appears in list 2 without using count()

trying to write this code to see how many times the numbers in list 1 appear in the list two, can use a nested for or while loop but I came up with this it doesn't work. I don't want to use count.
list1 = [4,7,2]
list2 = [2,3,4,2,5,6,3,2,6,7,3,4]
def compare(list1, list2):
freq = ([i for i in list1 if i == num])
return
print('The number 4 occurs in list2', freq, 'times')
print('The number 7 occurs in list2', freq, 'times')
print('The number 2 occurs in list2', freq, 'times')
I'm not completely sure that I understand the question,
but this code seems to work, though if it may be slow if you need it for an interactive program.
Hope this helps!
list1 = [4,7,2]
list2 = [2,3,4,2,5,6,3,2,6,7,3,4]
occurrences = [0,0,0]
for i in range(len(list1)):
for j in list2:
if list1[i] == j:
occurrences[i]+=1
print occurrences
try this:
list1 = [4,7,2]
list2 = [2,3,4,2,5,6,3,2,6,7,3,4]
occurrences = [0,0,0]
for i in range(len(list1)):
for j in list2:
if list1[i] == j:
occurrences[i]+=1
print occurrences

Subtract value in one data frame from the next value in a second data frame

I have a data frame that is composed of several datasets (about 146 and counting). two of my columns are labeled "start_time" and "stop_time," which represent the start and stop of a response (i.e., the total duration of the response).
I need to get the "inter-response time" or the start_time subtracted from the next corresponding value in start_time. Basically if:
start_time = [1,4,7]
stop_time = [2,5,8]
I need:
stop_time[0] - start_time[1]
stop_time[2] - start_time[3]
in order to get:
iri = [2,2]
My code looks like this:
iri_t = []
def grps():
for grp in lset2_name_grps.groups:
beg_eng_t = pd.DataFrame([lset2_name_grps.stop_time, lset2_name_grps.start_time], columns=['end_t','beg_t'])
end_t = [i for i in lset2_name_grps.stop_time]
beg_t = [i for i in lset2_name_grps.start_time]
beg_t = np.insert(beg_t, len(beg_t),0)
end_t = np.insert(end_t, 0,0)
iri_t.append(np.subtract(end_t, beg_t))
# for i,j in zip(end_t, beg_t):
# iri_t.append(np.subtract(i,j))
# lset2_name_grps['iri'] = iri_t
grps()
Essentially, it doesn't do anything close to what I'm trying to accomplish and the only out I get is either "Not Implemented" or an error.
How about something like this:
import pandas as pd
starts = pd.Series([1, 4, 7])
stops = pd.Series([2, 5, 8])
iri_t = [0]
for i in range(1, len(starts)):
iri_t.append(starts[i] - ends[i-1])
times_df = pd.concat([starts, stops, pd.Series(iri_t)], axis=1)
This creates the following data_frame:
0 1 2
0 1 2 0
1 4 5 2
2 7 8 2
I think what your asking (correct me if I'm wrong) is best accomplished by putting the two columns in a single dataframe, using shift to offset one of your columns, then doing an ordinary subtraction.
df = pd.DataFrame({'start_time':[1,4,7], 'stop_time':[2,5,8]})
df.stop_time - df.start_time.shift()
Out[5]:
0 NaN
1 4
2 4
dtype: float64

Enumerate list values into a list of dictionaries

I have a list of dictionaries, and I'm trying to assign dictionary key:value pairs based on the values of other other variables in lists. I'd like to assign the "ith" value of each variable list to ith dictionary in block_params_list with the variable name (as a string) as the key. The problem is that while the code appropriately assigns the values (as demonstrated by "pprint(item)"), when the entire enumerate loop is finished, each item in "block_params_list" is equal to the value of the last item.
I'm at a loss to explain this behavior. Can someone help? Thanks!
'''empty list of dictionaries'''
block_params_list = [{}] * 5
'''variable lists to go into the dictionaries'''
ran_iti = [False]*2 + [True]*3
iti_len = [1,2,4,8,16]
trial_cnt = [5,10,15,20,25]
'''the loops'''
param_list= ['iti_len','trial_cnt','ran_iti']#key values, also variable names
for i,item in enumerate(block_params_list):
for param in param_list:
item[param] = eval(param)[i]
pprint(item) #check what each item value is after assignment
pprint(block_params_list) #prints a list of dictionaries that are
#only equal to the very last item assigned
You've hit a common 'gotcha' in Python, on your first line of code:
# Create a list of five empty dictionaries
>>> block_params_list = [{}] * 5
The instruction [{}] * 5 is equivalent to doing this:
>>> d = {}
>>> [d, d, d, d, d]
The list contains five references to the same dictionary. You say "each item in 'block_params_list' is equal to the value of the last item" - that's an illusion, there's effectively only one item in "block_params_list" and you are assigning to it, then looking at it, five times over through five different references to it.
You need to use a loop to create your list, to make sure you create five different dictionaries:
block_params_list = []
for i in range(5):
block_params_list.append({})
or
block_params_list = [{} for i in range(5)]
NB. You can safely do [1] * 5 for a list of numbers, or [True] * 5 for a list of True, or ['A'] * 5 for a list of character 'A'. The distinction is whether you end up changing the list, or whether you change a thing referenced by the list. Top level or second level.
e.g. making a list of numbers, assinging to it does this:
before:
nums = [1] * 3
list_start
entry 0 --> 1
entry 1 --> 1
entry 2 --> 1
list_end
nums[0] = 8
after:
list_start
entry 0 -xx 1
\-> 8
entry 1 --> 1
entry 2 --> 1
list_end
Whereas making a list of dictionaries the way you are doing, and assigning to it, does this:
before:
blocks = [{}] * 3
list_start
entry 0 --> {}
entry 1 --/
entry 2 -/
list_end
first_block = blocks[0]
first_block['test'] = 8
after:
list_start
entry 0 --> {'test':8}
entry 1 --/
entry 2 -/
list_end
In the first example, one of the references in the list has to change. You can't pull a number out of a list and change the number, you can only put a different number in the list.
In the second example, the list itself doesn't change at all, you're assigning to a dictionary referenced by the list. So while it feels like you are updating every element in the list, you really aren't, because the list doesn't "have dictionaries in it", it has references to dictionaries in it.