DEV Community

Super Kai (Kazuya Ito)
Super Kai (Kazuya Ito)

Posted on • Edited on

Byte string in Python (4)

Buy Me a Coffee

*Memos:

You can access the byte string of a bytes literal or bytes() by indexing or slicing as shown below:

*Memos:

  • The byte string of a bytes literal and bytes() is mutable.
  • Slicing can be done with one or more [start:end:step]:
    • start(Optional-Default:The index of the 1st element).
    • end(Optional-Default:The index of the last element - 1).
    • step(Optional-Default:1). *step mustn't be zero.
    • The [] with at least one : is slicing.
  • Slicing can do shallow copy.
v = b'abcdefgh'
v = bytes(b'abcdefgh')

print(v)
# b'abcdefgh'

print(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7])
print(v[-8], v[-7], v[-6], v[-5], v[-4], v[-3], v[-2], v[-1])
# 97 98 99 100 101 102 103 104
Enter fullscreen mode Exit fullscreen mode
v = b'abcdefgh'
v = bytes(b'abcdefgh')

print(v[:])
print(v[::])
# b'abcdefgh'

print(v[::2])
# b'aceg'

print(v[::-2])
# b'hfdb'

print(v[2:])
print(v[-6:])
print(v[2::])
print(v[-6::])
# b'cdefgh'

print(v[2::2])
print(v[-6::2])
# b'ceg'

print(v[2::-2])
print(v[-6::-2])
# b'ca'

print(v[:6])
print(v[:-2])
print(v[:6:])
print(v[:-2:])
# b'abcdef'

print(v[:6:2])
print(v[:-2:2])
# b'ace'

print(v[:6:-2])
print(v[:-2:-2])
# b'h'

print(v[2:6])
print(v[-6:-2])
print(v[2:6:])
print(v[-6:-2:])
# b'cdef'

print(v[2:6:2])
print(v[-6:-2:2])
# b'ce'

print(v[2:6:-2])
print(v[-6:-2:-2])
# b''
Enter fullscreen mode Exit fullscreen mode

You cannot change the byte string of a bytes literal or bytes() because it's immutable as shown below. *A del statement can still be used to remove a variable itself:

v = b'abcdef'
v = bytes(b'abcdef')

v[0] = b'X'
# v[-6] = b'X'
v[2:6] = [b'Y', b'Z']
# TypeError: 'bytes' object does not support item assignment
Enter fullscreen mode Exit fullscreen mode
v = b'abcdef'
v = bytes(b'abcdef')

del v[0]
# del v[-6]
del v[3:5]
# TypeError: 'bytes' object does not support item deletion
Enter fullscreen mode Exit fullscreen mode
v = b'abcdef'
v = bytes(b'abcdef')

del v

print(v)
# NameError: name 'v' is not defined
Enter fullscreen mode Exit fullscreen mode

If you really want to change the byte string of a bytes literal or bytes(), use bytearray(), ord() and bytes() as shown below.

v = b'abcdef'
v = bytes(b'abcdef')

v = bytearray(v)

v[0] = ord(b'X')
# v[-6] = ord(b'X')
v[2:6] = [ord(b'Y'), ord(b'Z')]

v = bytes(v)

print(v)
# b'XbYZ'
Enter fullscreen mode Exit fullscreen mode
v = b'abcdef'
v = bytes(b'abcdef')

v = bytearray(v)

del v[0]
# del v[-6]
del v[3:5]

v = bytes(v)

print(v)
# bcd
Enter fullscreen mode Exit fullscreen mode

In addition, if you really want to change the byte string of a bytes literal or bytes(), use list(), chr(), str.encode() and bytes.join() as shown below.

v = b'abcdef'
v = bytes(b'abcdef')

v = [chr(x).encode() for x in list(v)]

v[0] = b'X'
# v[-6] = b'X'
v[2:6] = [b'Y', b'Z']

v = b''.join(v)

print(v)
# b'XbYZ'
Enter fullscreen mode Exit fullscreen mode
v = b'abcdef'
v = bytes(b'abcdef')

v = [chr(x).encode() for x in list(v)]

del v[0]
# del v[-6]
del v[3:5]

v = b''.join(v)

print(v)
# b'bcd'
Enter fullscreen mode Exit fullscreen mode

You can access the byte string of bytearray() by indexing or slicing as shown below:

v = bytearray(b'abcdefgh')

print(v)
# bytearray(b'abcdefgh')

print(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7])
print(v[-8], v[-7], v[-6], v[-5], v[-4], v[-3], v[-2], v[-1])
# 97 98 99 100 101 102 103 104
Enter fullscreen mode Exit fullscreen mode
v = bytearray(b'abcdefgh')

print(v[:])
print(v[::])
# bytearray(b'abcdefgh')

print(v[::2])
# bytearray(b'aceg')

print(v[::-2])
# bytearray(b'hfdb')

print(v[2:])
print(v[-6:])
print(v[2::])
print(v[-6::])
# bytearray(b'cdefgh')

print(v[2::2])
print(v[-6::2])
# bytearray(b'ceg')

print(v[2::-2])
print(v[-6::-2])
# bytearray(b'ca')

print(v[:6])
print(v[:-2])
print(v[:6:])
print(v[:-2:])
# bytearray(b'abcdef')

print(v[:6:2])
print(v[:-2:2])
# bytearray(b'ace')

print(v[:6:-2])
print(v[:-2:-2])
# bytearray(b'h')

print(v[2:6])
print(v[-6:-2])
print(v[2:6:])
print(v[-6:-2:])
# bytearray(b'cdef')

print(v[2:6:2])
print(v[-6:-2:2])
# bytearray(b'ce')

print(v[2:6:-2])
print(v[-6:-2:-2])
# bytearray(b'')
Enter fullscreen mode Exit fullscreen mode

You can change the byte string of bytearray() because it's mutable as shown below. *A del statement can be used to remove a variable itself:

v = bytearray(b'abcdef')

v[0] = ord(b'X')
# v[-6] = ord(b'X')
v[2:6] = [ord(b'Y'), ord(b'Z')]

print(v)
# bytearray(b'XbYZ')

print(bytes(v))
# b'XbYZ'
Enter fullscreen mode Exit fullscreen mode
v = bytearray(b'abcdef')

del v[0]
# del v[-6]
del v[3:5]

print(v)
# bytearray(b'bcd')

print(bytes(v))
# b'bcd'
Enter fullscreen mode Exit fullscreen mode
v = bytearray(b'abcdef')

del v

print(v)
# NameError: name 'v' is not defined
Enter fullscreen mode Exit fullscreen mode

The variables v1 and v2 refer to the same byte string unless copied as shown below:

*Memos:

  • is keyword can check if v1 and v2 refer to the same byte string.
  • Slicing can do shallow copy.
  • copy() and copy.copy() can also do shallow copy. *There are no arguments.
  • copy.deepcopy() can do deep copy. *There are no arguments.
  • deepcopy() should be used because it's safe, doing copy deeply while copy() isn't safe, doing copy shallowly.
import copy

v1 = bytearray('abcde'.encode())
v1 = bytearray(b'abcde')

v2 = v1 # v2 refers to the same byte string as v1.

v2[2] = ord('X') # Changes the same byte string as v1.
v2[2] = 88      
                        # ↓
print(v1) # bytearray(b'abXde')
print(v2) # bytearray(b'abXde') 
                        # ↑
print(v1 is v2) # True

v2 = v1[:]             # v2 refers to the different byte string from v1.
v2 = v1.copy()
v2 = copy.copy(v1)
v2 = copy.deepcopy(v1)

v2[2] = ord('Y') # Changes the different byte string from v1.
v2[2] = 89
                        # ↓
print(v1) # bytearray(b'abXde')
print(v2) # bytearray(b'abYde')
                        # ↑
print(v1 is v2) # False
Enter fullscreen mode Exit fullscreen mode

Top comments (0)