创建位列表?

时间:2018-11-10 14:47:36

标签: python list bit

当前,我有两个功能:char2binsegmentString

segmentString接受一个字符串和一个填充字符,并返回包含8个字符串的列表。例如,如果有一个13个字符串,则会将其拆分为两个字符串的列表,其中第二个字符串具有3个填充字符,以使其成为完整的8。

>>>segmentString("Hello, World!", "-")
['Hello, W', 'orld!---']

char2bin采用单个字符串字符(单个字符),并将它们转换为8位列表。它不适用于多个字符串。例如,

>>>char2bin('a')
[0,1,1,0,0,0,0,1]
>>>char2bin('abc')
(ERROR)

我需要创建一个函数(在本示例中,将其称为成帧器),该函数从segmentString中获取结果并将其转换为位列表,其中每个位列表都包含在列表中的单独列表中。 / p>

例如,从segmentString函数,这将创建两个字符串的列表。每个单独的字符串的每个字母都转换为一个位列表,每个位列表都包含在每个字符串的列表中。

>>>F=framer("Hello, World!", "-")
>>>F
[[[0, 1, 0, 0, 1, 0, 0, 0], [0, 1, 1, 0, 0, 1, 0, 1], [0,1, 1, 0, 1, 1, 0, 0], [0, 1, 1, 0, 1, 1, 0, 0], [0, 1, 1, 0, 1, 1,1,1], [0, 0, 1, 0, 1, 1, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0], [0, 1,1, 1,0, 1, 1, 1]], [[0, 1, 1, 0, 1, 1, 1, 1], [0, 1, 1, 1, 0, 0,1, 0], [0,1, 1, 0, 1, 1, 0, 0], [0, 1, 1, 0, 0, 1, 0, 0], [0, 0,1, 0, 0, 0, 0,1], [0, 1, 1, 1, 1, 1, 1, 0], [0, 1, 1, 1, 1, 1,1, 0], [0, 1, 1, 1,1, 1, 1, 0]]]

如您所见,有一个常规列表,其中包含两个包含8个位列表的列表,这些位是由char2bin从字符串字符转换而来的。 我该怎么办?

3 个答案:

答案 0 :(得分:1)

您可以为此使用列表理解:

def char2bin(byte):
    return list(map(int, format(byte, '08b')))

def segmentString(text, padding, chunksize):
    for index in range(0, len(text), chunksize):
        yield text[index:index + chunksize].ljust(chunksize, padding)

def framer(text, padding='-', chunksize=8, encoding='utf8'):
    return [[char2bin(byte) for byte in segment] for segment in
            segmentString(text.encode(encoding), padding.encode(encoding), chunksize)]

这使用utf8编码,但是由于您输入的文本均为ascii字符,因此每个字符只有一个字节。

>>> framer('Hello, World!')
[[[0, 1, 0, 0, 1, 0, 0, 0],
  [0, 1, 1, 0, 0, 1, 0, 1],
  [0, 1, 1, 0, 1, 1, 0, 0],
  [0, 1, 1, 0, 1, 1, 0, 0],
  [0, 1, 1, 0, 1, 1, 1, 1],
  [0, 0, 1, 0, 1, 1, 0, 0],
  [0, 0, 1, 0, 0, 0, 0, 0],
  [0, 1, 0, 1, 0, 1, 1, 1]],
 [[0, 1, 1, 0, 1, 1, 1, 1],
  [0, 1, 1, 1, 0, 0, 1, 0],
  [0, 1, 1, 0, 1, 1, 0, 0],
  [0, 1, 1, 0, 0, 1, 0, 0],
  [0, 0, 1, 0, 0, 0, 0, 1],
  [0, 0, 1, 0, 1, 1, 0, 1],
  [0, 0, 1, 0, 1, 1, 0, 1],
  [0, 0, 1, 0, 1, 1, 0, 1]]]

非ASCII字符需要多个位进行编码。

>>> framer('', padding='\x00')
[[[1, 1, 1, 1, 0, 0, 0, 0],
  [1, 0, 0, 1, 1, 1, 1, 1],
  [1, 0, 0, 1, 0, 0, 1, 0],
  [1, 0, 1, 0, 1, 0, 0, 1],
  [0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0]]]

答案 1 :(得分:0)

您可以使用列表推导,也可以使用itertools模块。

您可以了解有关列表理解here的更多信息,以及有关itertootls here的更多信息。

答案 2 :(得分:0)

您可以使用以下代码实现目标。

def segment_string(s, fill_by):
    l = []
    while s:
        if len(s) < 8:
            s = s + (fill_by) * (8 - len(s))

        l.append(s[0:8])
        s = s[8:]   

    return l  # ['Hello, W', 'orld!---']

def char2bin(ch):
    a = bin(ord(ch))[2:]
    l = [int(c) for c in a]

    if len(l) < 8:
        l = ([0] * (8 - len(l))) + l # Adding extra 0s to front (if len(l) < 8)

    return l # [0, 1, 0, 0, 1, 0, 0, 0]

def framer(s, fill_by='-'):
    segments = segment_string(s, fill_by) # Calling segment_string()
    print(segments)

    arr = []
    for segment in segments:
        arr2 = []
        for ch in segment:
            arr3 = char2bin(ch); # Calling char2bin()
            arr2.append(arr3)

        arr.append(arr2)

    return arr # final list to be returned


if __name__ == "__main__":
    f = framer('Hello, World!', '~')
    print(f)
输出»
[[[0, 1, 0, 0, 1, 0, 0, 0], [0, 1, 1, 0, 0, 1, 0, 1], [0, 1, 1, 0, 1, 1, 0, 0], [0, 1, 1, 0, 1, 1, 0, 0], [0, 1, 1, 0, 1, 1, 1, 1], [0, 0, 1, 0, 1, 1, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0], [0, 1, 0, 1, 0, 1, 1, 1]], [[0, 1, 1, 0, 1, 1, 1, 1], [0, 1, 1, 1, 0, 0, 1, 0], [0, 1, 1, 0, 1, 1, 0, 0], [0, 1, 1, 0, 0, 1, 0, 0], [0, 0, 1, 0, 0, 0, 0, 1], [0, 1, 1, 1, 1, 1, 1, 0], [0, 1, 1, 1, 1, 1, 1, 0], [0, 1, 1, 1, 1, 1, 1, 0]]]

# >>> bin(126)
# '0b1111110'
# >>>
# >>> chr(126)
# '~'
# >>>