For Loop for specific numbers - python

I am trying to write a for loop such that it only contains numbers between 1 and 7 (both inclusive) and the numbers get stored in a list.
The length of the list should be 8629.
This is the code which i try to run. I get this error: SyntaxError: invalid syntax
random_list = []
for i in range(0,8628):
x = i % 7
random_list[i].append(x+1)
while i == i + 1
print(random_list)

if your requirement is :
The length of the list should be 8629 and write a for loop such that it only contains numbers between 1 and 7. shouldn't it be like this?
from random import *
random_list = []
while len(random_list) < 5:
random_list.append(randint(1, 7))
print(random_list)

random_list = [i % 7 + 1 for i in range(8628)]
print(random_list)
The list will be :[1,2,3,4,5,6,7,...........]

This will give random integers in the range you specified:
Code
import random
random_list = [random.randint(1, 7) for _ in range(8629)]
Test
random_list[:10]
# [3, 4, 4, 5, 3, 1, 3, 7, 7, 6]
min(random_list), max(random_list)
# (1, 7)
len(random_list)
# 8629
For a cycle of consecutive numbers, try itertools:
Code
import itertools as it
cycled_list = list(it.islice(it.cycle(range(1, 8)), 8629))
Test
cycled_list[:10]
# [1, 2, 3, 4, 5, 6, 7, 1, 2, 3]
min(cycled_list), max(cycled_list)
# (1, 7)
len(cycled_list)
# 8629
See #Ming Chu's post for list compression variant.

Related

Count cycles in a permutated list

I am trying to make a function that counts the number of cycles within a permutated list.
I do sometimes get the right answer when running the code, but most times I receive an error message - and I am unable to figure out why.
My code is as follows:
def count_cycles(n):
cycle_count = 0
copy_list = []
for element in n:
copy_list.append(element)
while len(copy_list) != 0:
ran_num = random.choice(copy_list)
while True:
if n[ran_num] == ran_num:
cycle_count = circle_count + 1
if int(ran_num) in copy_list:
copy_list.remove(ran_num)
break
else:
n.insert(ran_num, ran_num)
print(n, ran_num, copy_list)
ran_num = n[ran_num + 1]
print(ran_num)
copy_list.remove(ran_num)
n.remove(ran_num)
continue
return print(cycle_count, n)
What I use is that I test with this permutated list with 3 cycles [2, 6, 0, 3, 1, 4, 5].
Picture of output from a correct and incorrect run
I used print(n, ran_num, copy_list) to assess the output as per the picture.
Here is one possibility:
p = [2, 6, 0, 3, 1, 4, 5]
cycles = set()
elts = set(range(len(p)))
while elts:
cycle = []
x0 = elts.pop()
cycle.append(x0)
x = p[x0]
while x != x0:
cycle.append(x)
x = p[x]
elts -= set(cycle)
cycles.add(tuple(cycle))
print(cycles)
It gives:
{(0, 2), (1, 6, 5, 4), (3,)}
Then to get the number of cycles you can use len(cycles).
In addition to the existing answer, sympy provides some functionality to work with permutations. In this case, you could use the following:
from sympy.combinatorics import Permutation
p = Permutation([2, 6, 0, 3, 1, 4, 5])
num_cycles = p.cycles # 3

Guide in understanding code - Splitting array on smaller arrays

I have a problem with understanding one process which is splitting array on smaller arrays. I'm posting the two lines below and I would appreciate if you could explain to me what certain part does. Thank you in advance :)
my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9]
# How many elements each
# list should have
n = 4
final = [my_list[i * n:(i + 1) * n] for i in range((len(my_list) + n - 1) // n )]
# Almost the same code with some changes:
def split_list(alist, wanted_parts=1):
length = len(alist)
return [ alist[i*length // wanted_parts: (i+1)*length // wanted_parts]
for i in range(wanted_parts) ]
A = [0,1,2,3,4,5,6,7,8,9]
what is your problem?
you have the initial list
my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9]
for example, you want to split it on 3 parts. So you call function
split_list(my_list, wanted_parts =3)
inside function, you will have:
length = len(alist) # it will be 9
then you have this:
for i in range(wanted_parts) # range(3), so it would be i = [0,1,2]
then you have:
alias[xxxx:yyyy] # where xxxx - start point of slice and yyyy - end point of slice, and you have it 3 times and pass there i = (0,1,2)
now lets check xxxx. in your case it is:
i*length // wanted_parts # i=0..2, length = 9, wanted_parts = 3, so all of this = 0, 3, 6
now lets check yyyy. in your case it is:
(i+1)*length // wanted_parts. # i = 0..2, (i+1) = 1..3, length = 9, wanted_parts = 3, so all of this = 3, 6, 9
so totaly you will have:
[0:3], [3:6], [6:9] # - and it will be 3 parts of your list

how do you distribute a number throughout a certain amount of fields?

Okay so lets say I have number , 100, and I want to split it up into 12 groups randomly and have the total from all the groups equate to 100. How would I do this, I have written a piece of code but it has a flaw.
from random import randint
total = 100
while total < 101:
for i in range(0,9):
num = randint(1,total)
print(i,"|","*"*num)
total -= num
if total <= 0:
for j in range (i,10):
print(j,"|","*"*total)
when you run it , once the total is equal to zero or less, it crashes, so it wont post the full results and I do not know how to deal fix this. I'm new to Python so my knowledge is limited.
Splitting a number n into k groups randomly is mathematically equivalent to randomly placing k-1 dividers. Thus, I would do something like this:
from random import randint
def split_randomly(n,k):
dividers = set() # guarantee no duplicate dividers
while len(dividers) < k-1:
dividers.add(randint(1,n-1))
dividers = [0] + sorted(dividers) + [n]
return [dividers[i+1] - dividers[i] for i in range(len(dividers)-1)]
For a proper random split, you could use random.sample. THe following gathers a sample of k-1 random split points from [1..n] and 0 and n and returns a list of their pairwise differences:
from random import sample
def split(n, k):
splits = [0] + sorted(sample(range(1, n), k-1)) + [n]
return [end-start for start, end in zip(splits, splits[1:])]
>>> split(10, 7)
[1, 3, 1, 1, 1, 1, 2]
>>> split(10, 7)
[1, 1, 1, 1, 1, 4, 1]
>>> split(10, 7)
[1, 2, 2, 1, 2, 1, 1]
>>> split(100, 12)
[10, 10, 8, 5, 7, 15, 1, 5, 1, 8, 26, 4]

Python: replace 20% of a list

I am trying to randomly replace 20% of a list in python:
ls = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
ls = [1, 2, NULL, 4, 5, 6, NULL, 8, 9, 10]
ls = [1, 2, 82, 4, 5, 6, 28, 8, 9, 10]
so far
while n <= len(ls)/5
ls[randint(0, 9)]=randint(1, 100)
n += 1
but it has a fairly large chance of removing and replacing the same entry multiple times in one run.
Assuming ls could be anything, I would recommend generating a list of indices, corresponding to ls. Then, you may use random.sample to pick up 20% of those indices, and then alter those only.
From the docs:
Return a k length list of unique elements chosen from the population
sequence. Used for random sampling without replacement.
In [816]: for _i in random.sample(range(len(ls)), len(ls) // 5):
...: ls[_i] = random.randint(1, 100)
...:
In [817]: ls
Out[817]: [1, 92, 3, 4, 5, 6, 7, 8, 75, 10]
Unless your lists are very large, you can select a sample from the indexes. For example:
for idx in random.sample(range(len(ls)), len(ls)/5):
ls[idx]=random.randint(1, 100)
You can shuffle a range of indexes and then take first n indexes that has to be changed.
from random import shuffle
x = [[i] for i in range(10)]
shuffle(x)
#change x[0], x[1], .. x[n-1]
If you want to eliminate the chance of the same index getting replaced the second time, you can store the result of randint(0, 9) in a variable. In the next iterations, use an if condition to check if randint() returned the same index as the previous iteration. If yes, then continue and do not increment n.
Alternatively, you can use random.sample() to pick up a given number of samples - 20% of the list size in your case.
Best option would be to pick 20% worth of indexes and then replace them in the list. Something like:
from random import randint
twenty_percent = round(len(ls) / 5)
for i in range(twenty_percent):
ls[randint(0, len(ls) - 1)] = randint(1, 100)
This answer takes INDEX into account, so it won't replace the same value twice.
ls = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
n = len(ls)
x = round(n/5)
for i in range(x):
index = randint(0, n)
del ls[index]
ls.insert(index, randint(0, 100))
print(ls)
Works for me. See if it does the job.

Python random list

I'm new to Python, and have some problems with creating random lists.
I'm using random.sample(range(x, x), y).
I want to get 4 lists with unique numbers, from 1-4, so I have been using this
a = random.sample(range(1, 5), 4)
b = random.sample(range(1, 5), 4)
c = random.sample(range(1, 5), 4)
d = random.sample(range(1, 5), 4)
So I get for example
a = 1, 3, 2, 4
b = 1, 4, 3, 2
c = 2, 3, 1, 4
d = 4, 2, 3, 1
How can I make it that the column are also unique?
Absent a clear mathematical theory, I distrust anything other than a somewhat hit-and-miss approach. In particular, backtracking approaches can introduce a subtle bias:
from random import shuffle
def isLatin(square):
#assumes that square is an nxn list
#where each row is a permutation of 1..n
n = len(square[0])
return all(len(set(col)) == n for col in zip(*square))
def randSquare(n):
row = [i for i in range(1,1+n)]
square = []
for i in range(n):
shuffle(row)
square.append(row[:])
return square
def randLatin(n):
#uses a hit and miss approach
while True:
square = randSquare(n)
if isLatin(square): return square
Typical output:
>>> s = randLatin(4)
>>> for r in s: print(r)
[4, 1, 3, 2]
[2, 3, 4, 1]
[1, 4, 2, 3]
[3, 2, 1, 4]
Totally random then:
def gen_matrix():
first_row = random.sample(range(1, 5), 4)
tmp = first_row + first_row
rows = []
for i in range(4):
rows.append(tmp[i:i+4])
return random.sample(rows, 4)
Create a list of all the elements, and as will filling the line, remove the used element.
import random
def fill_line(length):
my_list = list(range(length))
to_return = []
for i in range(length):
x = random.choice(my_list)
to_return.append(x)
my_list.remove(x)
return to_return
x = [fill_line(4)
for i in range(4)]
print(x)
Probably the simplest way is to create a valid matrix, and then shuffle the rows, and then shuffle the columns:
import random
def random_square(U):
U = list(U)
rows = [U[i:] + U[:i] for i in range(len(U))]
random.shuffle(rows)
rows_t = [list(i) for i in zip(*rows)]
random.shuffle(rows_t)
return rows_t
Usage:
>>> random_square(range(1, 1+4))
[[2, 3, 4, 1], [4, 1, 2, 3], [3, 4, 1, 2], [1, 2, 3, 4]]
This should be able to create any valid matrix with equal probability. After doing some reading it seems that this still has bias, although I don't fully comprehend why yet.
I would build a random latin square by 1) start with a single random permutation, 2) populate the rows with rotations 3) shuffle the rows 4) transpose the square 5) shuffle the rows again:
from collections import deque
from random import shuffle
def random_latin_square(elements):
elements = list(elements)
shuffle(elements)
square = []
for i in range(len(elements)):
square.append(list(elements))
elements = elements[1:] + [elements[0]]
shuffle(square)
square[:] = zip(*square)
shuffle(square)
return square
if __name__ == '__main__':
from pprint import pprint
square = random_latin_square('ABCD')
pprint(square)

Categories

Resources