Cantor space 2N to function

How can I use map() with count(0,float(‘inf’)) to create a never ending series of 1s and 0s?

count(0,float(‘inf’)) is a syntax error, count(0,float('inf')) doesn’t make sense, and it’s unclear what you want and what this has to do with Cantor. Please fix/clarify.

It’s a syntax error cuz you didn’t import itertools or from itertools import count.

Cantor space is a mathematical concept that represents an infinite sequence of 0s and 1s. It’s named after the mathematician Georg Cantor. Each element in the Cantor space is a sequence where each position can be either 0 or 1. For example, a sequence could be 0101010101… and so on. The Cantor space contains all possible sequences of 0s and 1s.

Syntax errors have nothing to do with missing imports.

To “create a never ending series of 1s and 0s” you can for example use cycle([1, 0]).

Still unclear why you want to use map() and count(0,float(‘inf’)) (especially the latter).

Actually, there is nothing wrong as such with

from itertools import count
it = count(0, float('inf'))

except that it reaches infinity in two steps, so doesn’t generate a sequence of 0’s and 1’s:

>>> next(it)
>>> next(it)
# and now it will forever stay there

Yeah, I know. But that doesn’t seem useful.

No, import errors are not syntax errors. count(0,float(‘inf’)) is a syntax error because it is using symbols rather than proper quotation marks. But either way, the correct code is just count(), or count(0). The second argument for itertools.count is a step value, not an endpoint. It doesn’t make sense to add inf each time - you’ll just get 0 the first time and inf every other time.

Aside from that, while itertools.count will work with floating-point values, it’s intended to be used with integers - because if it’s asked to use floating-point values, floating-point error can accumulate with repeated addition:

>>> import itertools
>>> list(itertools.islice(itertools.count(0.1, 0.3), 25))
[0.1, 0.4, 0.7, 1.0, 1.3, 1.6, 1.9000000000000001, 2.2, 2.5, 2.8, 3.0999999999999996, 3.3999999999999995, 3.6999999999999993, 3.999999999999999, 4.299999999999999, 4.599999999999999, 4.899999999999999, 5.199999999999998, 5.499999999999998, 5.799999999999998, 6.099999999999998, 6.399999999999998, 6.6999999999999975, 6.999999999999997, 7.299999999999997]

You can’t make an iterator that gives you all the values in the Cantor space, because there (by definition) are uncountably (not just infinitely) many such values.

If you want to iterate over every possible floating-point value between 0 and 1, then you should add the floating-point epsilon each time. But this doesn’t have anything to do with getting “a never ending series of 1s and 0s”. Each value that you get this way will be an ordinary floating-point number, which uses only 53 (a finite number - proof left as an exercise :wink: ) bits of precision (and 10 bits for an exponent, and 1 bit for a sign).

If you want to “decode” a real number into a potentially-infinite binary expansion, that would require you to have some representation of that real number in the first place. Computers don’t work like that. If you just want “a never ending [sequence] of 1s and 0s”, then you should just start with an object that represents that sequence. Floating-point numbers don’t do that. For example, math.pi does not represent the mathematical constant π, except by convention; rather, it represents the rational fraction 884279719003555 / 281474976710656 (which you can find out yourself using the as_integer_ratio method of the float type).

For example, itertools.cycle([1,0]) produces an object that represents a never-ending series of 1s and 0s - with the rule that it will alternate between 1 and 0. If you want an object that represents the binary digits of π (the actual mathematical value, not the constant from the math module), then you will need code that can calculate arbitrarily many such digits. For example, there is a well-known formula for the hexadecimal digits of π that allows calculating them in a “random access” way (i.e., without calculating everything that comes before). We could turn that fairly simply into a generator for bits in the binary expansion of π, something like:

def bbp_spigot(n):
    """Compute the nth hexadecimal digit of pi. Returns an integer in [0, 15]."""
    # TODO

def pi_bits():
    for i in itertools.count():
        hex_digit = bbp_spigot(i)
        for shift in [3, 2, 1, 0]:
            yield (hex_digit >> shift) & 1

I’d say it was. Until 3.1, which explicitly allowed non-integers. And its documentation shows count(2.5, 0.5) --> 2.5 3.0 3.5 ... as one of two examples.

Not sure what you mean with “the floating-point epsilon”, but you can use math.nextafter to go through them, that’s probably easier than what you have in mind.

Possibly. I did think of it (although I didn’t recall the method name), but that doesn’t drop in to the itertools.count interface. It doesn’t even readily work with the two-argument form of iter, because of the need to maintain state. It also requires Python 3.9 or above. Alternately, in 3.12 one could use the steps argument and map over a `count, sure.

So did you mean using some fixed epsilon as the step in count(0, epsilon)? That doesn’t produce every possible floating-point value between 0 and 1.

1 Like

What does itertools.cycle([1,0]) output?

Is the documentation unclear and is something preventing you from trying it?