2

When you run the script below in Python, you get the results shown.

1) I don't understand why it's able to print c just fine, but when I say z = shuffle(c) z returns zero. Shouldn't it just give me a mixed up c?

import random 
a = list(range(1,99))   
b = list(range(1,99))   
c =list(range(1,99))   
print(c)   
x=random.shuffle(a)     
y=random.shuffle(b)  
z=random.shuffle(c)   
print(x)   
q=(x,y,z)   
print(q)    

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98]   
None   
(None, None, None)

2) Ideally, I want make lots of q points each of which is given an x, y and z so q1=(x1,y1,z1) and q2=(x2,y2,z2) etc. So I thought I could iterate over it, but I'm not sure how to write it in less mathematical terms and more of a python way.
I tried

for i in range(len(x,y,z)):   
    q=(x[i],y[i],z[i])

But I don't think that's how Python works.

q-l-p
  • 4,304
  • 3
  • 16
  • 36
tgmjack
  • 57
  • 7
  • Please fix your code format – ᴀʀᴍᴀɴ May 16 '18 at 16:14
  • Do you want all `99 * 99 * 99` permutations of these? If so, try `itertools` – user3483203 May 16 '18 at 16:15
  • not every possible combination, just 99 q's – tgmjack May 16 '18 at 16:16
  • `random.shuffle` operates in place and returns `None`. There are a billion dupes about this (also for `list.sort`), hopefully somebody will find one. – wim May 16 '18 at 16:17
  • Just use `zip(a, b, c)` after calling `random.shuffle`, and don't bother assigning the result of `random.shuffle` to a variable, as it is an in-place operation. – user3483203 May 16 '18 at 16:18
  • @wim I can't find a good match for the question, but here's a reasonably generic answer from Martelli: https://stackoverflow.com/a/1682601/4014959 – PM 2Ring May 16 '18 at 16:26
  • @PM2Ring Too late, 5 answers already.. :) – wim May 16 '18 at 16:28
  • As the answer linked in my previous comment says, it's a Python convention for functions or methods which mutate their arg in-place to return `None`. Almost all the built-ins and standard library modules follow that convention, and so do most 3rd party libraries. Alex mentions there are a couple of exceptions, but even those don't return the mutated object. – PM 2Ring May 16 '18 at 16:30
  • Your code has made me curious. Is there a reason you want your 98 points to have that particular distribution rather than something more random? – PM 2Ring May 16 '18 at 16:47

6 Answers6

3

First, random.shuffle is an in-place operation. Second, you can use zip to combine your shuffled lists into points.

import random

x = list(range(1, 99))
y = list(range(1, 99))
z = list(range(1, 99))

random.shuffle(x)
random.shuffle(y)
random.shuffle(z)

points = list(zip(x, y, z))

If you are using Python 2.X, you can omit all of the list casts because range and zip will already be returning lists.

Jared Goguen
  • 8,772
  • 2
  • 18
  • 36
1

Look at the Docs.

random.shuffle modifies your list in place and returns nothing. Thus, you want

>>> a = list(range(1,99))  
print(a)
>>> random.shuffle(a)
print(a)

To get a random sample of your 3 lists, use random.sample

>>> n = 10 # for example
>>> list(zip(random.sample(a, n),random.sample(b, n),random.sample(c, n)))
user3483203
  • 50,081
  • 9
  • 65
  • 94
rafaelc
  • 57,686
  • 15
  • 58
  • 82
0
  1. z=random.shuffle(c) returns NoneType because, it simply modifies an array in-place! If you want a shuffled version, you need only do

random.shuffle(c)

print(c)

c will now be shuffled in place! You can then maybe create a deep copy of c.

This is sort of similar to how the sort function works!

a = [1, 4, 5, 9, 28, 1]

a.sort()

a is sorted in-place, doing something like b = a.sort(), would've led to storing NoneType in b

ababuji
  • 1,683
  • 2
  • 14
  • 39
0

As said in the comments, random.shuffle works on the list object and doesn't return anything. To get your code to shuffle and create a list of 3D points can be done easily

import random 
x = list(range(1,99))   
y = list(range(1,99))   
z = list(range(1,99))
random.shuffle(x)     
random.shuffle(y)  
random.shuffle(z)    

points = []
for i in range(len(x)):
    points.append((x[i], y[i], z[i]))

print(points)

Note this requires x, y and z to be the same length

adammoyle
  • 199
  • 1
  • 13
0

To answer q1: Shuffle is an in-place operation. Just shuffle(a) etc, to get random lists.
q2. You're looking for the builtin zip(), which will return a list of tuples, stopping at the end of the shortest input iterator.

AWooll
  • 1
0

Using numpy you could do something in the lines of:

import numpy as np

n = 3
ar = np.array([np.arange(100) for _ in range(3)])
for i in range(n):
    np.random.shuffle(ar[i])

list(map(tuple, np.dstack(ar)[0]))
Anton vBR
  • 18,287
  • 5
  • 40
  • 46