1

I am able to generate the desired output but i need 10 of them and each list has to be unicue. The best solution i thought of was to create a 2nd function, generate a emty list and populate each element with list from 1st function. The output i got so far is x amount of lists but they are not unique and python gives me error when i try to call on the first function inside the 2nd one.


import random

numbers = list(range(1, 35))
out = []
final = []
print(numbers)  # to see all numbers

# returns 7 unique pop'd numbers from list 'numbers' and appends them to list 'out'
def do():
    for x in range(7):
        out.append(numbers.pop(random.randrange(len(numbers))))

    print(sorted(out))


# In other words i want to print output from function do() 10 times but each item in list has to be unique, not the lists themself

def do_ten():
    for x in range(10):
        final.append(out)
        # do()  python doesnt like this call 
    print(sorted(final))


do_ten()
  • 2
    Does this answer your question? [Generate 'n' unique random numbers within a range](https://stackoverflow.com/questions/22842289/generate-n-unique-random-numbers-within-a-range) – LocoGris Sep 12 '20 at 11:50

4 Answers4

0

This generates a specific amount of lists, in a list, which contain random numbers from 1 to 100, you can use l and n to control the amount of lists and numbers respectively.

import random

l, n = 3, 5 # The amount of lists and numbers respectively.
lis = [[i for i in random.sample(range(1, 35), n)] for group in range(l)]
print(lis)

Random Output:

[[16, 11, 17, 13, 9], [26, 6, 16, 29, 24], [24, 2, 4, 1, 20]]
solid.py
  • 2,782
  • 5
  • 23
  • 30
  • you can get the same list multiple times : `[[1,2,3,4],[1,2,3,4],...]` – Patrick Artner Sep 12 '20 at 12:11
  • its random. Use `l, n = 30, 1` - it is principially possible to get thirty lists of length 1 that are unique if you have the numbers of 1..34 to choose from - buts its highly unlikely to do so. increasing `n` will lessen the chance to get the same numbers but it is still possible. nothing in your code _prevents_ getting the same list randomly twice – Patrick Artner Sep 12 '20 at 12:18
  • @PatrickArtner It runs just fine, you said so just now, and the answer here also validates that https://stackoverflow.com/questions/22842289/generate-n-unique-random-numbers-within-a-range So why downvote me and Sergey? Out of spite? Also you have the same code in the `final` variable, which is similar to what I posted earlier than you. – solid.py Sep 12 '20 at 12:20
0

Does it help:

num_lists = 10
len_list = 10 

[list(np.random.randint(1,11,len_list)) for _ in range(num_lists)]

As some people may have different definitin of "uniqueness", you may try:

source_list = range(0, num_lists*len_list,1)
[list(np.random.choice(source_list, len_list, replace=False)) for _ in range(num_lists)]
Sergey Bushmanov
  • 23,310
  • 7
  • 53
  • 72
  • Its not - you can, by random chance, get multiple lists (with unique values) that themself are duplicate: simplified `[[1,2,3,4],[1,2,3,4],...]` or can you not? – Patrick Artner Sep 12 '20 at 12:09
0

You are popping 10 times 7 numbers from a list containing 34 elements (from 1 to 34). This is not possible. You need to have at least 70 elements in your list numbers(for example, from 0 to 69).

This is a solution that should work, based on the code you've already written:

import random

numbers = list(range(0, 70))
final = []
print(numbers)  # to see all numbers

# returns a list of 7 unique popped numbers from list 'numbers'
def do():
    out = []
    for x in range(7):
        l = len(numbers)
        r = random.randrange(l)
        t = numbers.pop(r)
        out.append(t)
    return out

# Call 10 times do() and add the returned list to 'final'
def do_ten():
    for x in range(10):
        out = do() # Get result from do()
        final.append(out) # Add it to 'final'

do_ten()
print(final)
BNilsou
  • 886
  • 8
  • 22
-1

Pulling 7 of 34 numbers from your numberrange without repeats can be done using random.sample - to ensure you do not get duplicate lists, you can add a tuple of the list to a set and your final result and only add to final if this tuple is not yet in the set:

import random

numbers = range(1, 35)  # 1...34

final = []
chosen = set()
while len(final) < 10:
    # replace popping numbers with random.sample
    one_list = random.sample(numbers, k=7) # 7 numbers out of 34 - no repeats
    # create a tuple of this list and only add to final if not yet added
    t = tuple(one_list)
    if t not in chosen:
        chosen.add(t)
        final.append(one_list)

print (final)

Output:

[[1, 5, 10, 26, 14, 33, 6], 
 [3, 11, 1, 30, 7, 21, 18], 
 [24, 23, 28, 2, 13, 18, 1], 
 [4, 25, 32, 15, 22, 8, 27], 
 [32, 9, 10, 16, 17, 26, 12], 
 [34, 32, 10, 26, 16, 21, 20], 
 [6, 34, 22, 11, 26, 12, 5], 
 [29, 17, 25, 15, 3, 6, 5], 
 [24, 8, 31, 28, 17, 12, 15], 
 [6, 19, 11, 22, 30, 33, 15]]

If you dont need unique resulting lists, you can simplify this to a one-liner but it might have dupes inside:

final = [random.sample(range(1,11),k=7) for _ in range(10)]
Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
  • Yeah this gives me the output i want. But i have an intch to solve this using pop(). I get the reult i want with just the first for loop, but i only get it once. Is there a way to make it print it 10 times (not the same list 10 times over) insted of pressing run 10 times? – Dennis Aus. Sep 12 '20 at 12:41
  • @dennis put `numbers = ..` and `out = ...` inside `do()` ( before your loop). don't print in `do()` instead `return out`. in `do_ten()` change `final.append(out)` to `final.append(do())` - you might get the same list twice if you are very unlucky though - because it might randomly generate the same list in different calls to do(). Using "pop" is highly inefficient - you essentially create a list of 34 numbers, then you shrink that list by popping from it in random location wich needs data copying – Patrick Artner Sep 12 '20 at 12:52