Shuffle in Python - python

Is there a straightforward way to RETURN a shuffled array in Python rather than shuffling it in place?
e.g., instead of
x = [array]
random.shuffle(x)
I'm looking for something like
y = shuffle(x)
which maintains x.
Note, I am not looking for a function, not something like:
x=[array]
y=x
random.shuffle(x)

sorted with a key function that returns a random value:
import random
sorted(l, key=lambda *args: random.random())
Or
import os
sorted(l, key=os.urandom)

It would be pretty simple to implement your own using random. I would write it as follows:
def shuffle(l):
l2 = l[:] #copy l into l2
random.shuffle(l2) #shuffle l2
return l2 #return shuffled l2

Just write your own.
import random
def shuffle(x):
x = list(x)
random.shuffle(x)
return x
x = range(10)
y = shuffle(x)
print x # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print y # [2, 5, 0, 4, 9, 3, 6, 1, 7, 8]

There is no function you are looking for. Just copy a list.

You could use numpy.random.permutation for either a list or array, but is the right function if you have a numpy array already. For lists with mixed types, converting to a numpy array will do type conversions.
import numpy as np
my_list = ['foo', 'bar', 'baz', 42]
print list(np.random.permutation(my_list))
# ['bar', 'baz', '42', 'foo']

Using this as a demo elsewhere so thought it may be worth sharing:
import random
x = shuffleThis(x)
def shuffleThis(y):
random.shuffle(y)
return(y)
#end of Shuffle Function
Hope this is useful.

Related

Array Prints like List but its a single integer in variable explorer? Why?

When ı print out the following code Q is prints like it suppose to be (3 5 7 9) sum of the numbers with the next one. but in the variable explorer its a single integer ı want to get the result Q as an array like
Q = [3, 5, 7, 9]
import numpy as np
A = [1, 2, 3, 4, 5]
for i in range(0,4):
Q = np.array(A[i]+A[i+1])
print(Q)
for i in range(0,4):
Q = []
Q.append(Q[i] + A[i]+A[i+1])
print(Q)
This also doesnt work
Currently you're just re-declaring Q each time and it's never added to some collection of values
Instead, start with an empty list (or perhaps a numpy array in your case) and outside of your loop and append the values to it at each loop cycle
Q is a numpy array, but it's not what you're expecting!
It has no dimensions and only references a single value
>>> type(Q)
<class 'numpy.ndarray'>
>>> print(repr(Q))
array(9)
>>> import numpy as np
>>> A = [1, 2, 3, 4, 5]
>>> Q = np.array([], dtype=np.uint8)
>>> for i in range(4):
... Q = np.append(Q, A[i]+A[i+1]) # reassign each time for np
...
>>> print(Q)
[3 5 7 9]
Note that numpy arrays should be reassigned via np.append, while a normal python list has a .append() method (which does not return the list, but directly appends to it)
>>> l = ['a', 'b', 'c'] # start with a list of values
>>> l.append('d') # use the append method
>>> l # display resulting list
['a', 'b', 'c', 'd']
If you're not forced to use a numpy array to begin with, this can be done with a list comprehension
The resulting list can also be made into a numpy array afterwards
>>> [(x + x + 1) for x in range(1, 5)]
[3, 5, 7, 9]
All together with simplified math
>>> np.array([x*2+3 for x in range(4)])
array([3, 5, 7, 9])
If you want to use Numpy, then use Numpy. Start with a Numpy array (one-dimensional, containing the values), which looks like this:
A = np.array([1, 2, 3, 4, 5])
(Yes, you initialize it from the list).
Or you can create that kind of patterned data using Numpy's built-in tool:
A = np.arange(1, 6) # it works similarly to the built-in `range` type,
# but it does create an actual array.
Now we can get the values to use on the left-hand and right-hand sides of the addition:
# You can slice one-dimensional Numpy arrays just like you would lists.
# With more dimensions, you can slice in each dimension.
X = A[:-1]
Y = A[1:]
And add the values together element-wise:
Q = X + Y # yes, really that simple!
And that last line is the reason you would use Numpy to solve a problem like this. Otherwise, just use a list comprehension:
A = list(range(1, 6)) # same as [1, 2, 3, 4, 5]
# Same slicing, but now we have to do more work for the addition,
# by explaining the process of pairing up the elements.
Q = [x + y for x, y in zip(A[:-1], A[1:])]

How to remove an element that appears more than once in a list without changing the length of the list (no sets)

I've looked up many times and it seems that sets are the best option however for this assignment I believe it is not allowed. So, basically, I made an empty list and it generates a list that is 5 elements long with numbers between 1 and 9 inside. But all the numbers need to appear once in the list. How do I do that?
import random
lis = []
for i in range(1,6):
x = random.randint(1,9)
lis.append(x)
I've tried,
if x not in lis:
lis.append(x)
But the length of my list kept changing.
IIUC, You can use a while alongside the if statement you were originally trying:
import random
lis = []
while len(lis) < 5:
x = random.randint(1,9)
if x not in lis:
lis.append(x)
>>> lis
[2, 8, 1, 5, 3]
But if you want to be tricky about it, you can do:
x = list(range(1,10))
random.shuffle(x)
>>> x[:5]
[2, 1, 4, 3, 7]
Or
import numpy as np
>>> np.random.choice(range(1,10),5,replace=False)
array([7, 5, 3, 6, 4])
You could do this like Sacul said with a while loop, but here's another fancy option, it might not be allowed by your assignment though.
import random
lis = random.sample(range(1,10),5)

builtin_function_or_method' object has no attribute shuffle

Hi I am trying to define a function that returns a shuffled list l1 without changing the original list l using the method random.shuffle but I got this error message:
builtin_function_or_method object has no attribute shuffle
import random
def shuffle_list(l):
l1=random.shuffle(l)
return(l1)
from random import shuffle
def shuffle_list(l):
def shuffle_list(l):
shuffle(l)
return l
Import shuffle directly and return l and don't save it into any variable because l1 = shuffle(l) will return None
I know this is coming late.
Replace all instances of random.shuffle() with shuffle() after changing the import random with from random import shuffle.
random.shuffle() modifies the list in-place and doesn't return anything, so you need to first make a copy of the list argument, shuffle, and then return it, in order to preserve the original:
import random
def shuffle_list(lst):
lst2 = lst.copy()
random.shuffle(lst2)
return lst2
items = list(range(10))
shuffled = shuffle_list(items)
print(items) # => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(shuffled) # => [6, 2, 1, 9, 3, 0, 8, 4, 5, 7] (or some other rearrangement)
random.shuffle changes the order of the list in place and returns None.
>>> lst = [1,2,3]
>>> shuffle_list(lst)
>>> print lst
[3, 1, 2]
>>> shuffle_list(lst)
>>> print lst
[1, 3, 2]
So if you don't care about the order of the original list, your code could simply be:
import random
random.shuffle(l)

How can I select entries from list in random order in python

Question is simple. I have a list of say 10 entries, I am running a loop over it. What i want here is getting each entry exactly once but in random order.
What is the best and most pythonic way to do it?
You can use random.sample, it returns random elements preventing duplicates:
>>> import random
>>> data = range(10)
>>> print(random.sample(data, len(data)))
[2, 4, 8, 7, 0, 5, 6, 3, 1, 9]
The original list remains unchanged.
You can use random.shuffle:
In [1]: import random
In [3]: a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [4]: random.shuffle(a)
In [5]: a
Out[5]: [3, 6, 9, 1, 8, 0, 4, 7, 5, 2]
Shuffle the list first by importing the random module and using the shuffle function:
import random
x = ... # A list
random.shuffle(x)
Then loop over your list. Note that shuffle mutates the original list and does not return the shuffled version.
You could use shuffle:
import random
random.shuffle(yourlist)
# loop as you would normally
for item in yourlist:
.....
you could use random.shuffle():
import random
original = range(10)
# Make a copy of the original list, as shuffling will be in-place
shuffled = list(original)
random.shuffle(shuffled)
Valid remark from Jean-François Fabre: if you were to use the original variable and pass it directly to random.shuffle, Python would return an error, stating 'range' object does not support item assignment, as range returns a generator.
To solve this, simply replace the assignment with list(range(10)).
import random
s=set(range(10))
while len(s)>0:
s.remove(random.choice(yourlist(s)))
print(s)

Create a list of 100 integers whose values equal their indexes

Create a list of 100 integers whose value and index are the same, e.g.
mylist[0] = 0, mylist[1] = 1, mylist[2] = 2, ...
Here is my code.
x_list=[]
def list_append(x_list):
for i in 100:
x_list.append(i)
return(list_append())
print(x_list)
Since nobody else realised you're using Python 3, I'll point out that you should be doing list(range(100)) to get the wanted behaviour.
Use range() for generating such a list
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(10)[5]
5
for i in 100 doesn't do what you think it does. int objects are not iterable, so this won't work. The for-loop tries to iterate through the object given.
If you want to get a list of numbers between 0-100, use range():
for i in range(100):
dostuff()
The answer to your question is pretty much range(100) anyway:
>>> range(100)[0]
0
>>> range(100)[64]
64
You can use range(100), but it seems that you are probably looking to make the list from scratch, so there you can use while:
x_list=[]
i = 0
while i<100:
x_list.append(i)
i += 1
Or you could do this recursively:
def list_append(i, L):
L.append(i)
if i==99:
return L
list_append(i+1, L)
x_list = []
list_append(0, x_list)
print x_list
Also can use List Comprehensions, like
[x for x in range(100)]
If you want to import numpy you could do something like this:
import numpy as np
x_list = np.arange(0, 100).tolist()
Should work in python2.7 and python3.x
import random
data1=[]
def f(x):
return(random.randrange(0,1000))
for x in range (0,100):
data1.append(f(x))
data1

Categories