1

I have a list and I'm trying to do a loop for each item in the list, all at the same time.

I've tried using this code:

thelist = ['first', 'second', 'third']

def loop():
    while True:
        for x in thelist:
            x = str(x)
            time.sleep(5)
            do_stuff_that_includes_x()

But it does the stuff in the loop one by one as sorted in thelist.

And I want it to do the stuff for all items in thelist at the same time.

Thanks in advance.

mgilson
  • 300,191
  • 65
  • 633
  • 696
Taha
  • 1,592
  • 2
  • 18
  • 24
  • 2
    If you really want that, use threads. But if you explain why you want this, we might be able to provide simpler alternatives. – Thomas Jul 03 '12 at 14:01
  • 4
    Could you please tell what exactly you are trying to do? – sloth Jul 03 '12 at 14:01
  • What do you mean with "at the same time"? Python programs are sequential, they will execute the code step by step, unless you start using [threads](http://docs.python.org/library/thread.html). The entire point of a loop, in general, is to do execute the body of the loop repeatedly, i.e. "one by one" for as many repetitions as required by the loop logic. – unwind Jul 03 '12 at 14:01
  • For example, I want to `print` each item in `thelist` all at the same moment, not step by step. I want all the items that exists in `thelist` start their process at the same moment (parrallel). – Taha Jul 03 '12 at 15:08

4 Answers4

3

As has been noted in the comments by vossad01, your code has a 5 seconds delay inside your loop. This will cause a five second delay between any two items on the list. If you remove the 5 second delay, your messages will be sent to all rooms in the list near-instantaneous.

thelist = ['first', 'second', 'third']

def loop():
    while True:
        for x in thelist:
            x = str(x)
            do_stuff_that_includes_x() 

        time.sleep(5)
Hans Then
  • 10,935
  • 3
  • 32
  • 51
2

I think you need multi-processing:

import time

def work(x):
    x = str(x)
    time.sleep(5)
    print x
#   do_stuff_that_includes_x()

thelist = ['first', 'second', 'third']
from multiprocessing import Pool
p = Pool( len( thelist ) )
p.map( work, thelist )
Marco de Wit
  • 2,686
  • 18
  • 22
2

First, multithreaded parallelization does not tend to yield performance increases because of the Global Interpreter Lock (GIL). Thus, if you are doing this for performance reasons you will need to look at the multiprocessing module. See how do I parallelize a simple python loop? for an example of using the map member of of a process pool to accomplish this.

Side notes: It is bad form to re-assign the iterating variable (x). Additionally, since you want parallel execution it will be easiest if you can make do_stuff_that_includes_x() parametrized on x.

Community
  • 1
  • 1
vossad01
  • 11,552
  • 8
  • 56
  • 109
  • No, I'm not trying to increase performance. Let's say I have 3 accounts, I want all of the three accounts to send a message to a target account at the same time, not to send it one by one. – Taha Jul 03 '12 at 15:43
  • You do realize there is no such thing as "at the same time" unless you send a single message? Otherwise you would essentially need to have at least 3 cores (one dedicated to each account) all in perfect synchronization, which is not how things work. Maybe you need to provide more information as to what you are trying to accomplish? – vossad01 Jul 03 '12 at 15:59
  • Hmm, I have made a bot for chatrooms in some server. The bot uses 5 connections (5 accounts) to stay in the chatroom and post a message every few minutes (to avoid being auto kicked.), what I want is to set those bots in several chatrooms not just one and I want them to post the message in each room synchronized. The loop I posted above goes one by one, that means: the accounts post the message in **first** room after 5 seconds. the accounts post the message in **second** room after 5*2 seconds. // // // in **third** room after 5*3 seconds. And so on.. Hope I provided enough details this time – Taha Jul 03 '12 at 16:45
  • Why not just move the time.sleep(5) to be within the `while` loop but outside of the `for` loop. Then it will do all of them, wait 5 seconds, then do all of them, wait... – vossad01 Jul 03 '12 at 16:58
  • Tried that and still.. 5 accounts post the message in the first room THEN the second room and so on. – Taha Jul 03 '12 at 17:09
  • Right, but without the 5 second interval between them. Unless whatever is sending the messages supports grouping the messages and sending them in a batch there will always be 3 messages that are going to be sent and arrive in some order. Even if the entire process were executing purely in parallel from your python code all the way through to their chat server, that does not give you synchronization throughout. The Internet will not make any guarantees that all your packets are all treated equally in transit. Thus, one may (will) arrive at the server before another. – vossad01 Jul 03 '12 at 17:32
  • If the issue is that your code for sending the message take too long so things happens seconds apart we can probably do something about that, with the mentioned multiprocessing being an option. If the issue is that they do not arrive at the chat server at the same millisecond, then I think you should revisit your requirements. – vossad01 Jul 03 '12 at 17:33
  • I'm aware of the miliseconds delay, I don't mind that. The delay between each chatroom *after the first chatroom* is time.sleep(5)*1+1. That's because the code attempts to send messages to the first room (5 sec), then second room (5 seconds after the first 5 seconds, that makes them 10 sec), then third room (15 sec delay) and so on.. Got me? – Taha Jul 03 '12 at 17:48
  • Yes, and your code includes a 5 second delay between them that causes that behavior, I suggested moving that outside of the loop so that it does all of them, then waits 5 seconds. Then the delay between each is simply the time it takes to execute which should be much less than 5 seconds each. – vossad01 Jul 03 '12 at 19:04
  • If I increased the delay, it will cause the same behaviour. For example if the delay is 5 minutes, the delay between each chatroom will be +5 minutes. All I'm trying to do is making a thread that sends messages, for each chatroom in `thelist` and make them all run together. – Taha Jul 03 '12 at 19:33
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/13426/discussion-between-ultimate-zero-and-vossad01) – Taha Jul 04 '12 at 21:01
0

use the * operator to unpack the whole list at once

do_stuff_that_includes_x(*x)
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
  • how can I do some functions with each element in `x`? I `x` is my list, and i pass `*x` as a parameter to function, how can I write a function that will multiply every element in list `x` by 10? – taga Oct 21 '19 at 13:03