The short answer is, your application becomes unresponsive because you've totally saturated your CPU with billions of operations being performed on a large dataset. While your program is stuck in those loops it can't do anything else and appears to lock up.
First, you're creating 100 million items using range()
. This operation alone isn't going to be very fast because that's a lot of items.
Next, you're looping over those 100 million items with a list comprehension and building an entirely new list. The comprehension seems pointless since you're just passing the value from range right through, but perhaps you're just simplifying it for the example.
Finally, you're using a for loop to once again loop over all those items in the newly generated list from the comprehension.
That's 3 loops and 3 lists; One for the range()
, another for the list comprehension and the third is the for loop. You're doing a lot of work creating huge lists multiple times.
The process of appending items to a list takes several operations and at 100 million items, that's 100Mhz * number-of-operations. For example, if it took 10 operations you're looking at about 1Ghz worth of processing time. These aren't real benchmarks, but they illustrate how doing a lot of little operations like this can quickly add up to a lot of CPU time. Not only that but copying at-minimum 100MB of data around in memory several times is going to take additional time as well. All of this leads to a lack of responsiveness because your CPU is totally saturated.
If you absolutely need to pre-build such a huge list, then make sure you only loop over it once and do all the work you need to do on that item at that time. That'll cut down on the number of times you recreate the list and save on memory since fewer lists will need to be stored in memory at the same time.
If all you really need is an incrementing number, you can use a generator to count up. Generators are far more efficient since they are "lazy"; They only "yield" a single value at a time, rather than returning a whole list at once
. In Python 2, xrange()
is a range generator that works exactly like range except that it yields a single value at a time, rather than creating a whole list at once and returning that.
for i in xrange(pow(10,8)):
# do some work with the current value of i
In Python 3, there is no xrange()
since the range()
function returns a generator by default (technically it's range
type, but it acts generally the same way).
Here's an explanation of the difference between range()
and xrange()
http://pythoncentral.io/how-to-use-pythons-xrange-and-range/
Lastly, if you really need to use huge lists like this, the Numpy library has all sorts of optimizations for "sparse lists" which act like regular lists but do some clever tricks to store seemingly millions of items efficiently.