Int to bytes conversion confusion

I am trying to convert an integer to bytes and am confused about what is happening. If I do this:

x=b’1’

I get:

print(x)
b’1’

However, when I do this:
y=1
x=bytes(y)

I get:

print(x)
b’\x01’

When I try to write the first ‘x’ to owfs, it works. When I try to write the 2nd ‘x’ to owfs it fails. What is the different between the 2 such that one works and the other doesn’t and how do I get the same thing converting a variable integer as when using a literal? TIA.

I am trying to convert an integer to bytes

Can you give more detail here, or what the end goal is? Do you mean the text of an integer (perhaps for passing to an external device), or some type of encoding of an integer value?

In your first example you’re creating a bytes object from the ASCII character 1. The bytes object holds the ASCII value and the ASCII character is printed. But the byte value inside is 49, not 1. These objects are equal:

>>> b'1'
b'1'
>>> chr(49).encode()
b'1'
>>> int.from_bytes(b'1', "big")
49

In your second example, you’re passing an integer into bytes(). But from the help we can see what is expected.

| bytes(int) -> bytes object of size given by the parameter initialized with null bytes

This says the integer sets the size of the object that is created, not the content within. I don’t understand why your example shows \x01. It should be \x00.

>>> x = 5
>>> bytes(x)
b'\x00\x00\x00\x00\x00'

The object is made up of 5 null bytes.

So for how to turn an integer into bytes depends on what you want. Do you want each byte in the object to be an integer value less than 256, or do you want to encode a potentially large int into a number of bytes, or do you want to encode a string representing an integer into bytes?

If you want the first one, the pass in the integers as an iterable (such as a list), even if there’s only one value.

>>> bytes([1])
b'\x01'
>>> bytes([1, 2, 3, 49, 70])
b'\x01\x02\x031F'

Sorry about not being clear. There was a typo in my 2nd example.

x=bytes([y])

I did not realize that b’1’ was converting a string rather than an integer. So do I need to convert the integer to a string then convert to bytes? I supposed I could do this since the integer will always be a 1 or 0:

if (y==0):
x=b’0’
else:
x=b’1’

But is there a better way that does not involve an if?

That depends on what you are trying to accomplish. I still haven’t seen what your goal is for the bytes object. You could certainly convert from a string if that’s what you’re looking for.

>>> str(x).encode()
b'1'

Or you could convert from numbers if that is useful.

Thanks. That is exactly what I was looking for.

You could use the to_bytes(size, byteorder) method:

>>> (0).to_bytes(2, 'little')
b'\x00\x00'

>>> (1).to_bytes(4, 'little')
b'\x01\x00\x00\x00'
>>> (1).to_bytes(4, 'big')
b'\x00\x00\x00\x01'

or a lookup table:

table = {0: b'\x00', 1: b'\x01'}
table[0]  # returns b'\x00'

but the simplest would probably be the if operator:

value = b'\x01' if x else b'\x00'

All three of these will behave slightly differently if your number is
out of range.

It sounds like you are planning to assemble a bytes object one bit at a
time. That’s likely to be slow. You should consider assembling the
numeric value first:

# untested
value = 0
for bit in bits:
    value = (value << 1) | bit

and then converting the bits to bytes in one go, using to_bytes.

As is often the case, what counts as “a better way” depends on what you
are doing with the bytes afterwards.

Thank but BowlOfRed gave me what I need. I just need one byte (1 or 0) for writing to an owfs device.