как случайным образом сгенерировать последовательность списка, которая ранее не наблюдалась в Python 3 - PullRequest
0 голосов
/ 11 января 2019

Предположим, у меня есть код на Python 3

X, Y, Z = 10, 20, 30
data = [[1,3,6],[8,15,29],[8,9,19]] # observe data

Тогда как я могу случайным образом сгенерировать n (не очень большие) элементы данных, которых нет в data.

Условие: элемент [a,b,c] должен быть не в data, а 0<a<X, 0<b<Y, 0<c<Z

[1,3,5] хорошо, так как его нет в data и его элемент удовлетворяет условию

[11,3,6] плохо, поскольку не удовлетворяет условию, 11>10

Например, когда n=4, я хочу список элементов, которые не являются дубликатами

newdata = [[1,6,6],[8,17,25],[2,6,11], [4,6,12]] 

Ответы [ 4 ]

0 голосов
/ 12 января 2019

Для более высокой производительности вы можете использовать Numpy и тот факт, что кортежи можно преобразовать в целочисленные и обратно, просто перечислив их (по мере перечисления z, y, x):

import numpy as np

x, y, z = 100, 200, 300
n = 1000

data = [[1,3,6],[8,15,29],[8,9,19]]
forbidden = [i[0]*y*z + i[1]*z + i[2] for i in data]
pool = np.arange(x*y*z)
mask = np.ones(pool.size, dtype=bool)
mask[forbidden] = False
pool = pool[mask]
newdata = np.random.choice(pool, n, replace=False)
newdata = [(i // (y*z), i // z, i % z) for i in newdata]
0 голосов
/ 11 января 2019

Это должно сделать это:

from random import randint

X, Y, Z = 10, 20, 30
data = [[1,3,6],[8,15,29],[8,9,19]]
n = 4

newdata = set()

for i in range(n):
    while True:
    l = [randint(1, X), randint(1, Y), randint(1, Z)]
    if l not in data:
        newdata.add(tuple(l))
        break

print(newdata)

Пример результата:

newdata = [(9, 9, 11), (10, 10, 4), (7, 6, 23), (2, 10, 4)]
0 голосов
/ 11 января 2019

В случае, если X, Y, Z не слишком велико, вы можете просто создать все возможные комбинации и затем произвести выборку из этого пула:

import itertools as it
import random

x, y, z = 10, 20, 30
pool = it.product(range(x), range(y), range(z))
data = [(1, 3, 6), (8, 15, 29), (8, 9, 19)]
pool = set(pool) - set(data)
n = 4
newdata = random.sample(pool, n)
0 голосов
/ 11 января 2019

Потребовалось небольшое усилие, но, похоже, это работает:

from random import *
from pprint import pprint

X, Y, Z = 10, 20, 30
data = [[1,3,6],[8,15,29],[8,9,19]]

while 1:
    newData = []
    try: n = int(input("How many lists do you want: "))
    except:
        print("Please enter an integer.\n")
        continue
    for i in range(n):
        newList = [randrange(1, X), randrange(1, Y), randrange(1, Z)]
        while (newList in data) or (newList in newData):
            newList = [randrange(1, X), randrange(1, Y), randrange(1, Z)]
        newData.append(newList)
    pprint(newData)

Это работает, создавая пустой список, получая значение для n, затем вводя цикл ровно из n итераций. Затем он создает новый список, который удовлетворяет требованиям. Если новый список находится в списке наблюдаемых данных, он просто делает это снова и снова, пока его нет в данных. Затем он добавляет эти данные в список вывода и повторяет процесс до тех пор, пока не прервется цикл for (после n итераций).

Возможно, есть лучший способ сделать это, но это помогает.

...