Reputation: 7573
I'm a complete nab with python. But now I need a simple storage containing MyObject-objects for some project. Each object contains a few StringProperties nothing fancy.
Now I want to get from my list of MyObjects, 10 random objects and store them in some other array.
So I went searching and found random.sample and started implemending it.
def get10RandomMyObjects():
# waarders maken
dict = {}
myObjectsList = []
# Lijst vullen
myObjects = MyObject.all()
randomMyObjects = random.sample(myObjects, 10)
for o in randomMyObjects:
dict_myObject = { }
#some random property setting
myObjectsList.append(dict_myObject)
dict['myObjects'] = myObjectsList
return dict
This is the error I get back:
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/random.py", line 314, in sample
n = len(population)
TypeError: object of type 'Query' has no len()
So obviously something is wrong with the random.sample but my noobness can't decypher what it is. Anyone care to explain me why I can't obtain those 10 random MyObjects I so desire?
Upvotes: 1
Views: 2670
Reputation: 3733
Looks like the Query object is a generator. random.sample
likes to know how many items there are in order to create the sample. So the simplest thing to do is put the items to be sampled in a list:
randomMyObjects = random.sample(list(myObjects), 10)
Upvotes: 2
Reputation: 8004
random.sample()
works on lists. Obviously, MyObject.all()
does not return a list but a Query
object. If Query
is at least iterable then you can write:
myObjects = list(MyObject.all())
Otherwise, you have to create a list from MyObject.all()
manually.
Upvotes: 2
Reputation: 20354
You may also use:
randomMyObjects = MyObject.all().order_by('?')[:10]
Which is faster because it will let the database do the random ordering and only load the 10 first objects into memory.
Upvotes: 1
Reputation: 25039
There is nothing wrong with random.sample()
. What is happening is that myObjects
is not a collection.
Most likely, myObjects
is an iterator. You'll have to turn it into a list before using it in random.sample()
:
randomMyObjects = random.sample(list(myObjects),10)
Upvotes: 1