The task is this: I have a BMP image with a size of 896x116 . I open it and ask these variables for two variables. Also, I need to divide 896 by 0x3 and 0x80 , which at the end is sent as 0x380 = 896 ; also with 116

 path = "logo.bmp" img = Image.open(path, "r") img.load() width = img.size[0] # получаем 896 height = img.size[1] # получаем 116 def bytes(num): # с помощью этого получаем 0x3 и 0x80 return hex(num >> 8), hex(num & 0xFF) 

Next, I want to do the following:

 address = [0x80, 0x03, 0x94] value = bytes(width)[1] # 0x3 value2 = bytes(width)[0] # 0x80 send = (address + value) 

And I get an error

 TypeError: can only concatenate list (not "str“) to list на send = (address + value) 

How to get rid of this error?

  • one
    You cast widths to bytes, then take an element from them. A single item in the byte collection is an integer. You cannot attach an integer to the list (address) simply by the addition operator. - insolor
  • one
    What is your version of Python? What result do you want: integer (int), bytes (bytes)? Perhaps you want struct.pack('!H', 896) or if the input number is not fixed in size, then int2bytes(896) - jfs
  • one
    Regarding the addition to the list jfs you already answered. Couple tips: do not use the name bytes - this is the name of the Python built-in type. To translate an integer into a set of bytes, instead of a bicycle, it is better to use the int.to_bytes() method, and the result is a list. In your case, it will look something like this: values = list(width.to_bytes(2, byteorder='little')) (“little” means the order of bytes from the youngest to the oldest (from 0x380 you get [0x80, 0x03] )) need the opposite, then write "big"). Then just take the values[0] and values[1] and use as you need. - insolor
  • one
    @Insider in Python strings and numbers are of a different type and b"\x03"[0] returns a string, not an integer in Python 2. Do you want to send the 2nd low byte of width ? b = (width >> 8) &0xFF; spi.xfer2(address + [b]) b = (width >> 8) &0xFF; spi.xfer2(address + [b]) . It is probably more convenient with bytearray() to work to create data to send if spi.xfer2(bytearray(b"\x80\x03\x94\x03")) works. - jfs
  • one
    To convert an int into a list of bytes, you can use this option: value = [ord(item) for item in struct.pack('>i', width)] - insolor

2 answers 2

In Python, lists, numbers, strings are represented by different types and the operation of addition for a mixture of these types is not defined. You can add lists with lists, lines with lines, numbers with numbers, but you cannot mix them up, otherwise you will get a TypeError as in the question.

@Avernial showed how you can add a number ( value ) to the list (creating a temporary list on the fly), that is, replace address + value with address + [value] . In addition, there are many other errors in the question (the definition of bytes , the expectation that [] returns an integer for strings).

Judging by the code , the spi.xfer2() function, mentioned in the comment , expects a sequence of bytes, represented as integers, therefore, as

 width = 896 # 03 80 byte = (width >> 8) & 0xff # 03 result = spi.xfer2([0x80, 0x03, 0x94] + [byte]) 

so and

 #!python2 width = 896 # 03 80 _, byte = struct.pack('<H', width) # "\3" result = spi.xfer2(bytearray("\x80\x03\x94") + byte) 

must produce the same byte sequence.

In both cases, you can call address.append(byte) instead of adding if the address is not used elsewhere (if you can change it at this location) and send the address directly instead of send : spi.xfer2(address) .

    If you want to add a value to the list, you can do it like this:

     send = address + [value] 
    • one
      The append method adds an element to the source list ( address ) and returns None (which will fall into the send variable). - insolor
    • Yes, true remark. - Avernial