【问题标题】:Convert list to string and then back to list将列表转换为字符串,然后返回列表
【发布时间】:2017-03-15 07:31:18
【问题描述】:

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

问题:
如何将数字列表转换为字符串然后重建列表?

文件内容:

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


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

在服务器中: 我将字符串映射回值列表。然后使用grouper 将该列表转换为元组列表(x, y, w)。然后(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"

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

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


编辑! 我尝试发送列表而不是字符串,但服务器不接受。

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

提前致谢!

【问题讨论】:

  • 有什么原因你没有在服务器上使用 .tostring 的倒数(例如:.fromstring)?
  • @JonClements str 对象没有 attr .fromstring
  • 如果 L 是您从客户端传输的字符串,那么当您执行 list(L) 时,您会将字节字符串分解为单个字节。您希望array.array('h', L) 将每个元素保留为两个字节。
  • 你不能只发送一个正确输入的array.array 。你的数字范围是多少?
  • @juanpa.arrivillaga 范围高达1,000,000

标签: python python-2.7


【解决方案1】:

在您的代码中:

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

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

>>> 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 - 'h' 格式是一个 2 字节有符号整数,因此您需要使用 'l' 作为有符号长整数,而不是充分表示值...(有关可用选项,请参阅array documentation 中的类型代码)

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-02
    • 1970-01-01
    • 1970-01-01
    • 2013-07-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多