将列表转换为字符串,然后返回列表

时间:2017-03-15 07:31:18

标签: python python-2.7

背景
我将数据转换为二进制,因为服务器端需要二进制类型。

问题:
如何将数字列表转换为String然后重新构建列表?

文件内容:

1 1 1
1 2 1
1 3 1
1 4 1
1 5 1
1 6 1
1 7 1
1 8 1
1 9 1
1 10 1
1 11 1
1 12 1
1 13 1
1 14 1
1 15 1


在客户端:我正在读取整个文件,将每个值附加到列表中。然后将列表转换为数组,在将数据发送到服务器之前将其转换为字符串。

在服务器中:我将字符串映射回值列表。然后使用(x, y, w)将列表转换为元组grouper的列表。然后将(x, y, z)提供给Point,并将新构造的对象附加到列表中。

注意我无法使用bytearray,因为这是一个人工数据样本,我的数字比byte所代表的要多得多。

代码:

from itertools import izip_longest
import array

def grouper(iterable, n, fillvalue=None):
    #Collect data into fixed-length chunks or blocks
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)

class Point:
    def __init__(self, x, y, w):
        self.x = x
        self.y = y
        self.w = w


if __name__ == "__main__":
    myList = []
    listOfObjects = []
    with open('data10mb.txt') as f:
        for line in f:
            s = line.split()
            x, y, w = [int(v) for v in s]
            myList.append(x)
            myList.append(y)
            myList.append(w)
    L = array.array('h', myList).tostring()


发送到服务器的数据

收到的数据

    myList = list(map(ord, list(L)))
    myList = list(grouper(myList, 3))
    s = len(myList)
    for i in range (0, s):
        x, y, w = myList[i]
        obj = Point(x, y, w)
        listOfObjects.append(obj)

预期输出:

1      <---- first line in file
1 
1
-------- 
1      <--- sixth line in file
7
1

实际输出:

1
0
1
1
0
4

我不确定我做错了什么..我4天前问了this问题。 "How to convert .txt file to a binary object"

服务器指定应发送的数据为:binary: A byte array。我不能在这里有一个简单的bytearray因为python bytearray仅限于保存数字0-256而且我文件中表示的数字要大得多。

我应该使用什么?至于上半部分,它的清晰数据是混合的,我在服务器端没有正确解析,或者我在代码中做错了,我看不到它......


修改<!/强> 我已经尝试发送列表而不是字符串,但服务器不接受。

  

TypeError:write()参数1必须是字符串或缓冲区,而不是列表。

提前致谢!

1 个答案:

答案 0 :(得分:1)

在您的代码中:

L = array.array('h', myList).tostring()

您正在创建一个打包为两个字节整数的字节串。在服务器端,您然后使用list(L)L的每个元素生成一个列表,但在这种情况下,它不会保留2字节的打包,因为它将bytestring中的每个元素视为单个字节,例如:

>>> import array
>>> a = array.array('h', [1234, 5678])
>>> s = a.tostring()
>>> s
b'\xd2\x04.\x16'
>>> list(s)
[210, 4, 46, 22] # oops - wrong!

因此,从源数据重建数组以获取您发送的内容。

>>> array.array('h', s)
array('h', [1234, 5678]) # better!

另请注意,在您的评论中,您说范围高达1,000,000 - &#39; h&#39; format是一个2字节有符号整数,所以你需要使用&#39; l&#39;对于签名长而不是足够代表值...(请参阅array documentation中的类型代码以获取可用选项)

to_send = array.array('l', [1000000, 12345]).tostring()
recieved = array.array('l', to_send)