Using the built-in map function :
map(q.put, items)
It will apply q.put to all your items in your list. Useful one-liner.
For Python 3, you can use it as following :
list(map(q.put, items))
Or also :
from collections import deque
deque(map(q.put, items))
But at this point, the for loop is quite more readable.
Using the built-in map function :
map(q.put, items)
It will apply q.put to all your items in your list. Useful one-liner.
For Python 3, you can use it as following :
list(map(q.put, items))
Or also :
from collections import deque
deque(map(q.put, items))
But at this point, the for loop is quite more readable.
What's unreadable about that?
for i in items:
q.put(i)
Readability is not the same as "short", and a one-liner is not necessarily more readable; quite often it's the opposite.
If you want to have a q.put(*items)-like API, consider making a short helper function, or subclassing Queue.
How do I pop multiple items from a queue? (python)
How to iterate Queue.Queue items in Python? - Stack Overflow
python - Get all items from thread Queue - Stack Overflow
Multiprocess.Queue only get some of items not all
Yes, use a tuple:
fruit = 'banana'
colour = 'yellow'
q.put((fruit, colour))
It will be automatically unpacked.
I just would make a list:
fruit = 'banana'
colour = 'yellow'
q.put([fruit, colour])
and then get it like that:
result = q.get()
fruit = result[0]
colour = result[1]
Specifically, I am wondering how to take all numbers less than 50 from a queue. I am not having trouble with adding numbers or moving them, but with removing them after they're moved. I am getting the following error: "IndexError: pop index out of range". I'm using VisualStudio Code if that matters.
You can loop over a copy of the underlying data store:
for elem in list(q.queue)
Eventhough this bypasses the locks for Queue objects, the list copy is an atomic operation and it should work out fine.
If you want to keep the locks, why not pull all the tasks out of the queue, make your list copy, and then put them back.
mycopy = []
while True:
try:
elem = q.get(block=False)
except Empty:
break
else:
mycopy.append(elem)
for elem in mycopy:
q.put(elem)
for elem in mycopy:
# do something with the elements
Listing queue elements without consuming them:
>>> from Queue import Queue
>>> q = Queue()
>>> q.put(1)
>>> q.put(2)
>>> q.put(3)
>>> print list(q.queue)
[1, 2, 3]
After operation, you can still process them:
>>> q.get()
1
>>> print list(q.queue)
[2, 3]
If you're always pulling all available items off the queue, is there any real point in using a queue, rather than just a list with a lock? ie:
from __future__ import with_statement
import threading
class ItemStore(object):
def __init__(self):
self.lock = threading.Lock()
self.items = []
def add(self, item):
with self.lock:
self.items.append(item)
def getAll(self):
with self.lock:
items, self.items = self.items, []
return items
If you're also pulling them individually, and making use of the blocking behaviour for empty queues, then you should use Queue, but your use case looks much simpler, and might be better served by the above approach.
[Edit2] I'd missed the fact that you're polling the queue from an idle loop, and from your update, I see that the problem isn't related to contention, so the below approach isn't really relevant to your problem. I've left it in in case anyone finds a blocking variant of this useful:
For cases where you do want to block until you get at least one result, you can modify the above code to wait for data to become available through being signalled by the producer thread. Eg.
class ItemStore(object):
def __init__(self):
self.cond = threading.Condition()
self.items = []
def add(self, item):
with self.cond:
self.items.append(item)
self.cond.notify() # Wake 1 thread waiting on cond (if any)
def getAll(self, blocking=False):
with self.cond:
# If blocking is true, always return at least 1 item
while blocking and len(self.items) == 0:
self.cond.wait()
items, self.items = self.items, []
return items
I think the easiest way of getting all items out of the queue is the following:
def get_all_queue_result(queue):
result_list = []
while not queue.empty():
result_list.append(queue.get())
return result_list