Random distribution in lists with python

Asked

Viewed 1,609 times

3

I have a list:

li = [0, 0, 2313, 1221, 0, 1333, 66, 0, 0, 0, 0]  

and another list of lists, where:

The list of lists is called disciplines (below). The lists that are within disciplines, are also specified below:

#essas são as listas que estão dentro de disciplinas:
cs = [2313, 2214, 2120]
gav = [1101, 1103, 1104]
icc = [3201, 3304, 3209]
comp = [4101, 4203, 4409, 4559]

#lista de listas
disciplinas = [cs, gav, icc, comp]

I need to pick by draw from the list disciplines a value (cs or gav or icc or comp). I thought about using the method choice(). After the value is chosen randomly, I must remove from disciplines and add in li in a random position of li, only where zero. I have to do this, as long as subjects are different from null.

OBS: I should add the value of disciplines only one in a row after the other, never isolated, so that it stays like this, for example:

li = [cs, cs, 2313, 1221, 0, 1333, 66, icc, icc, gav, gav]  

I have already found a way to distribute in the positions where zero is found (in the example below, I replaced 0 by 1), so that only the item can be placed if the current item_and currentitem_+1 OR current item_and current item_1 are equal to zero:

l = [0, 0, 2313, 1221, 0, 1333, 66, 0, 0, 0, 0]
lCount = len(l)
next1 = False
for i in range(0, lCount-1):
    if(l[i] == 0 and l[i+1] == 0):
        l[i] = 1
        l[i+1] = 1
        next1 = True
    if(next1): # ultimo elemento caso seja 0 seguido de outro (next1 definido no ultimo loop do ciclo)
        l[-1] = 1
print(l) # [1, 1, 2313, 1221, 0, 1333, 66, 1, 1, 1, 1]

Thank you very much!

  • 1

    Only where is one 0 followed by another right? Is it like your previous question? Whenever one is 0 followed by another 0 the two are changed to those values of disciplines

  • 1

    H+a a problem with "I must remove from disciplines and add in li", because if we remove the disc from the list disciplines every time we add one to l, then we will only be able to do this four times because the disciplines list will be empty at room 0 followed

  • Very correct Miguel, but no problem if only 4 loops are run in this case. The goal is this, because it is a genetic algorithm and this part that is being done is to generate an individual. I will make a list that stores all the individuals generated to generate the population :D

  • 1

    Ha but taking into account the final result you want and published in the question li = [cs, cs, 2313, 1221, 0, 1333, 66, icc, icc, gav, gav] , this is not executed only 4 times

  • True, but I have just given as an example to explain that they are dependent among themselves, for example: I can only add one discipline after another, but never in isolation. I just need when it’s randomly added to the list I read, it’s removed from the subjects, I don’t know if you can understand? Thank you very much! D

  • 1

    Yeah, but think about me, this example you gave, there are six places where we need to do the right insertion? But in our disciplines only 4... What happened in the last 2 0 in l in a row?

  • Perfect friend, excellent observation =) in my case, I did not put there not to get too much code, but I have actually a vector with 80 positions of zeros. And another vector disciplines with 50 positions. Will end up remaining place, but is that the very purpose :D has to do so? Already in the loop remove from disciplines?

  • 1

    Of course, so the moment there are no more disciplines does not add more right? and will remove as you add right? I’m gonna make

  • Done at the bottom @Allan

Show 4 more comments

2 answers

2


Exactly with Choice can do, should import module Random:

import random

cs = [2313, 2214, 2120]
gav = [1101, 1103, 1104]
icc = [3201, 3304, 3209]
comp = [4101, 4203, 4409, 4559]

disciplinas = [cs, gav, icc, comp]
l = [0, 0, 2313, 1221, 0, 1333, 66, 0, 0, 0, 0]

randDisc = [] # armazenamos os resultados sorteados para mais tarde remove-los da lista disciplinas
lCount = len(l)
next1 = False
for i in range(0, lCount-1):
    if(len(disciplinas) > 0):
        disc = random.choice(disciplinas)
        if(l[i] == 0 and l[i+1] == 0):
            l[i] = disc
            randDisc.append(disc)
            disciplinas.remove(disc)
            next1 = True
        elif(next1):
            l[i] = disc
            randDisc.append(disc)
            disciplinas.remove(disc)
            next1 = False
    else:
        break

print(l) # [[1101, 1103, 1104], [2313, 2214, 2120], 2313, 1221, 0, 1333, 66, [3201, 3304, 3209], [4101, 4203, 4409, 4559], 0, 0]
print(disciplinas) # []
  • Thank you very much Miguel! Show!

  • 1

    Hehe ball show. You’re welcome @Allan

  • An addendum to what was done: when printing the vector all positions are filled with zero. Think of a vector with size 80 full of zeros: li = [0] * 80

  • On average there are 50 values that I should add to this vector filled with zeros. But not all positions of the vector li should be filled, since I have 50 values and 80 empty positions (with zero). This code is adding in all positions of li. How could I fix this?

  • 1

    I didn’t get it. The goal is to switch in l all elements whose are 0 and the previous element is also 0 right? By a list element disciplinas

  • 1

    That is if we had: l = [0,0,0,5] stayed l = [randomDisc,randomDisc,randomDisc,5]. Right?

  • No haha is like this: the vector disciplines is the list of disciplines, in vdd a list list. See there in your code that only after all the execution, were removed the drawn disciplines. I am trying to make sure that during the loop, those that are drawn and added to randDisc are already removed from the discipline list. List positions l that are not filled by a list value disciplines, must remain zero. Got it? =)

Show 2 more comments

1

You can use the random to draw the value and the new position to be inserted. If the position is different from 0, try again.

import random as r
li = [None, None, 65123, 2223, 4536, None, None, None]

while(len(disciplina) > 0):
    p_rem = r.randint(0, len(disciplina)-1)
    v_rem = disciplina[p_rem]
    disciplina.remove(v_rem)

    while True:
        li_add = r.randint(0, len(li)-1)
        if not li[li_add]:
            li[li_add] = v_rem
            break
  • Thank you even Brumazzi DB!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.