Originally Posted by Mr909
Teach me another way to do what I did in the original trick in one line or less.
"One line" would be:
- python Code
# Python 3
These do in the background what you are trying to do above, but without going to the extra trouble of assembling a list result that will be discarded.
"less" would be:
- python Code
# Line below deleted to avoid coercing data objects
# to non-portable machine-level representations
# without explanation
| I mean, I totally get what you're saying, but to be honest I can't even tell you what proper usage for generators look like because I usually just use it to quickly, efficiently format lists. |
Without knowing anything about your use case I can't give you practical programming advice (why do you need to do this? why are you using array? etc.). You've posed an X Y problem.
But the more general question of how/why to use generators VS lists is a good question.
The short answer is that lists require all memory resources involved to be allocated through the entire life of the list plus e(n) processing time to initialize (an up-front cost). Generators, on the other hand, require a tiny, constant amount of memory and a trivial amount of time to initialize regardless the size of the set they represent, but are more expensive to access than lists.
The longer answer goes something like...
A list must contain all of its members for the duration of its life. A generator only need be aware of its last value and how that relates to the next value it should yield -- it generates
answers as it goes, it doesn't recall
them from memory. Generation is more expensive than recall, but it permits you to do things like ask the computer "tell me the next number after 314" instead of "remember every number from X to Y and tell me the next one". The generator approach lets you create lists of arbitrary size without worrying about how much memory that will suck up.
Consider the python2 example:
- python Code
# A list with 1 billion members... ouch!
for x in range(0, 1000000000):
# A generator containing only its instance variables
for x in xrange(0, 1000000000):
Pretty vast difference. In Python3 xrange() has been renamed range() and the old list version has been dropped entirely. If you want to iterate over a list you can still do that, just generate it on your own.
The generator approach also lets you define a dynamic range of values -- a range that may change in the middle of some other processing. Some folks consider this black magic -- and writing code like is certainly a way to outsmart yourself if you're not careful -- but it is useful in some cases. If the domains you are dealing with are large then generators are often the only
practical solution to such a problem, because there may not be enough processing time or memory in the world to generate a list for every variation of a dynamic domain as it evolves.
But in almost every case what you need is a list, not a generator. In the example above where you used 'string' as your target you're using a special form of tuple (a string), not a generator anyway, so this whole point is moot -- hence my reference to the array methods fromstring() and frombyte() (there is a from*() method for nearly any valid C array type on common architectures).