What is a generator and why would you use it? Without quoting any books, obviously (unless you can find a decent, simplistic answer direct from a book). Perhaps with examples, if you're feeling generous!
A generator is simply a function which returns an object on which you can call next, such that for every call it returns some value, until it raises a StopIteration exception, signaling that all values have been generated. Such an object is called an iterator.
Normal functions return a single value using return, just like in Java. In Python, however, there is an alternative, called yield. Using yield anywhere in a function makes it a generator. Observe this code:
Observe that a generator object is generated once, but its code is not run all at once. Only calls to next actually execute (part of) the code. Execution of the code in a generator stops once a yield statement has been reached, upon which it returns a value. The next call to next then causes execution to continue in the state in which the generator was left after the last yield. This is a fundamental difference with regular functions: those always start execution at the "top" and discard their state upon returning a value.
There are more things to be said about this subject. It is e.g. possible to send data back into a generator (reference). But that is something I suggest you do not look into until you understand the basic concept of a generator.
This code uses itertools.islice to take a finite number of elements from an infinite stream. You are advised to have a good look at the functions in the itertools module, as they are essential tools for writing advanced generators with great ease.
and so on. The (or one) benefit of generators is that because they deal with data one piece at a time, you can deal with large amounts of data; with lists, excessive memory requirements could become a problem. Generators, just like lists, are iterable, so they can be used in the same ways:
First of all, the term generator originally was somewhat ill-defined in Python, leading to lots of confusion. You probably mean iterators and iterables (see here). Then in Python there are also generator functions (which return a generator object), generator objects (which are iterators) and generator expressions (which are evaluated to a generator object).
According to the glossary entry for generator it seems that the official terminology is now that generator is short for "generator function". In the past the documentation defined the terms inconsistently, but fortunately this has been fixed.
As many other answers are showing, there are different ways to create a generator. You can use the parentheses syntax as in my example above, or you can use yield. Another interesting feature is that generators can be "infinite" -- iterators that don't stop:
When a function is a generator, it can return a value without the stack frame being discarded, using the yield statement. The values of local variables and the program counter within the function are preserved. This allows the generator to be resumed at a later time, with execution continuing from the yield statement, and it can execute more code and return another value.
Before Python 2.5 this was all generators did. Python 2.5 added the ability to pass values back in to the generator as well. In doing so, the passed-in value is available as an expression resulting from the yield statement which had temporarily returned control (and a value) from the generator.
The key advantage to generators is that the "state" of the function is preserved, unlike with regular functions where each time the stack frame is discarded, you lose all that "state". A secondary advantage is that some of the function call overhead (creating and deleting stack frames) is avoided, though this is a usually a minor advantage.
The only thing I can add to Stephan202's answer is a recommendation that you take a look at David Beazley's PyCon '08 presentation "Generator Tricks for Systems Programmers," which is the best single explanation of the how and why of generators that I've seen anywhere. This is the thing that took me from "Python looks kind of fun" to "This is what I've been looking for." It's at
yield behaves like return in the sense that values that are yielded get "returned" by the generator. Unlike return, however, the next time the generator gets asked for a value, the generator's function, foo, resumes where it left off -- after the last yield statement -- and continues to run until it hits another yield statement.
The yield statement is used in conjuction with Python generators. It saves the state of the function and returns the yeilded value. The next time you call the next() function on the generator, it will continue where the yield left off.
After I ran this that the memory is almost exactly the same and that's because the generator hasn't actually done anything yet it's not holding those million values in memory it's waiting for me to grab the next one.
As well and you can still use all of the comprehensions and this generator expression here so you don't lose anything in that area. So those are a few reasons why you would use generators and also some of the advantages that come along with that.
Inverters: The best gas-powered generators are inverter generators with carbon monoxide detection and Bluetooth monitoring. They should be manufactured by a company with an established reputation for generators. We also looked at similarly sized battery-powered models, and although their battery drain poses some limitations, these units sidestep the inconveniences of owning a gas engine.
Lastly, as mentioned earlier, inverter generators can pair up to double the available power. Two 2,200-watt generators linked together, for example, behave like a single 4,400-watt generator. Making this connection requires a parallel kit, usually sold separately. The ability to double up like this is a nice option to have, but it does bring the added responsibility of maintaining two engines instead of just one.
Bluetooth: Some generators are now equipped with an app and Bluetooth connectivity, which together allow you to monitor power usage, shut the engine off, and get an estimate of the time remaining until the gas runs out. This kind of information feedback removes a lot of wattage-guessing and lets you maximize the available power.
We also tested sound with a Triplett SoniCheck sound meter at the unit and at distances of 5, 10, and 25 feet. We tested them idling in eco mode with no electrical draw and also at around 1,500 watts. In general, inverters of this size are pretty quiet, especially in eco mode, when the engine ramps up and down depending on the draw. Even with the loudest models, we could have a conversation around the generator without needing to raise our voices too much.
Following those checks, we spent the majority of our testing just using the generators: adding and removing wattage, intentionally overloading the generators, seeing how easily they started with a cold engine. We also looked at the engine setup and how easy it would be to drain the oil and change the spark plug. User friendliness played a big role: Are the gauges simple to read? Are the instructions clear? We also looked at portability, moving the generators from place to place and hoisting them onto a truck tailgate.
More than any other generator we found, the RYi2322VNM emphasizes convenience and user-friendliness. It was the only generator we tested that had a readout of the current load and remaining time on the face of the unit. This information also displays in the Bluetooth app, where you can switch eco mode on and off and reset the generator in case of an overload so it begins producing power again. When other generators overload, you need to shut them off and restart them manually. All of these added features in the Ryobi app have the potential to prevent trips outside to the generator in inclement weather.
The overall look and feel is very similar to that of the gas generators we tested. It has a handle at each end and weighs roughly the same as the Honda EU2200i, about 45 pounds with the two batteries. We would prefer to see a single top handle as on the other models, which would make this unit much easier to carry with one hand.
We did test an inexpensive model, the TackLife 2000-Watt Portable Inverter Generator. Its build quality was disappointing, with none of the finesse of the other generators (and no CO-detection feature). When our test unit arrived, we needed to force open the access panels because the holding clips had been installed in the wrong location. This model simply failed to measure up to the others, and we see it as representative of low-cost models sold on Amazon by brands not typically associated with generators. As a final indicator of its poor quality, the TackLife completely disappeared from Amazon as we were writing this guide.
CMake Generators are platform-specific so each may be available onlyon certain platforms. The cmake(1) command-line tool--help output lists available generators on thecurrent platform. Use its -G option to specify thegenerator for a new build tree. The cmake-gui(1) offersinteractive selection of a generator when creating a new build tree.
Some of the CMake Generators listed in the cmake(1)command-line tool --help output may havevariants that specify an extra generator for an auxiliary IDE tool.Such generator names have the form - .The following extra generators are known to CMake.
A common use case of generators is to work with data streams or large files, like CSV files. These text files separate data into columns by using commas. This format is a common way to share data. Now, what if you want to count the number of rows in a CSV file? The code block below shows one way of counting those rows:
You can also define a generator expression (also called a generator comprehension), which has a very similar syntax to list comprehensions. In this way, you can use the generator without calling a function:
df19127ead