perl等价的python array.array(typecode,..)

时间:2011-07-04 00:27:24

标签: python arrays perl types

我正在尝试将python脚本翻译为perl,但目前只停留在几个代码snipets上。

例如如何在perl中编写以下python代码? (不使用任何与perl数组相关的包)

# packet here is a binary string
data = array.array( 'h', ( ord( packet[i] ) for i in range( start, end ) ) )
FILE.write(data);

我的(失败)尝试:

my @data;
foreach $i ( $start .. $end ) {
   $data[$i] = ord( substr( $packet, $i, 1) );  # Assuming that perl's ord = python's ord
}

print FILE @data;

@ysth ,实际输入是一个大型二进制文件,并且在这里发布我的第一个问题时,我忘记生成示例输入和输出,对不起。为了完整性,请在样本输入和输出下方找到。

输入:['a','b','c','d'] #think this as packet contents,start = 0,end = 4

在python中输出:

> cat py.out | xxd
0000000: 6100 6200 6300 6400                      a.b.c.d.

输出perl:

> cat pl.out | xxd
0000000: 3937 3938 3939 3130 30                   979899100

@Pedro Silva ,正如我在你的建议的第一行中所理解的,你只需用地图功能替换循环,效果是一样的。 解包'W *'返回错误,因为W不是有效类型(perl 5.8.8)。

1 个答案:

答案 0 :(得分:5)

修改

你需要澄清你在说什么。在我的python(2.7.2)上,这是错误的:

FILE.write(data)

因为data需要是一个字符串。我想你的意思是:

data.tofile(FILE)

无论如何,这是你想要的吗?

print pack("s*", unpack("C*", "abcd"))
# piped through xxd => 0000000: 6100 6200 6300 6400     a.b.c.d.

浏览perldoc -f pack以查找要使用的正确模板字符串。由于您无权访问W(unsigned wchar),因此我使用C(unsigned char)。 s是签名的短片(对应于python的h。)

<强> /修改

Perl中没有类型化数组。 ord返回其参数的第一个字符的数值。

假设这是您想要的,只需将每个字符上的$packet分割所得到的列表映射到@data,然后使用ord转换每个元素(参数$_为隐含地给出了。)

my @data = map { ord } split //, $packet; # or
my @data = unpack 'W*', $packet;          

(可选)使用与$packet上的实际下限和上限不同的范围:

(split //, $packet)[$start .. $end];    # or
 split //, substr $packet, $start, $end # ysth's version