unicode字符数组可用作可变字符串:
import array
ins = "Aéí"
ms = array.array('u', ins)
ms[0] = "ä"
outs = ms.tounicode()
# äéí
但是从Python 3.3开始不推荐使用类型'u'
。什么是现代替代品?
我能做到:
ms = list(ins)
# mutate
outs = ''.join(ms)
但是我发现与数组相比,字符列表的内存效率非常低。
可替换地:
ms = array.array('L', (ord(ch) for ch in ins))
ms[0] = ord("ä")
outs = "".join(chr(ch) for ch in ms)
但它的可读性远远低于已弃用的原版。
答案 0 :(得分:1)
这与您的上一个示例类似,但是以更具可读性和效率的方式初始化数组。您必须选择大小为四个字节的数组大小。 I
是unsigned int
的代码,在大多数操作系统上是4个字节。为了便于携带,您可能希望以编程方式选择此值。
#!coding:utf8
import array
import sys
# Verifying the item size.
assert array.array('I').itemsize == 4
# Choose encoding base on native endianness:
encoding = 'utf-32le' if sys.byteorder == 'little' else 'utf-32be'
ins = "Aéí"
ms = array.array('I',ins.encode(encoding))
ms[0] = ord('ä')
print(ms.tobytes().decode(encoding))
输出:
äéí
1000个元素字符串的计时显示速度要快得多:
In [7]: s = ''.join(chr(x) for x in range(1000))
In [8]: %timeit ms = array.array('I',s.encode('utf-32le'))
1.77 µs ± 14.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [9]: %timeit ms = array.array('I',(ord(x) for x in s))
167 µs ± 5.35 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [21]: %timeit outs = "".join(chr(x) for x in ms)
194 µs ± 4.98 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [23]: %timeit outs = ms.tobytes().decode('utf-32le')
3.92 µs ± 97 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
但你可能会过度思考它。我不知道你正在处理什么字符串大小,但只使用list(data)
更快,如果内存效率更低,并且它不是那么糟糕。这是一个非BMP字符列表(~1M),以及不可变字符串切片,变异数组和变异列表的时间:
In [67]: data = ''.join(chr(x) for x in range(0x10000,0x110000))
In [68]: ms = array.array('I',data.encode('utf-32le'))
In [69]: %%timeit global data
...: data = data[:500] + 'a' + data[501:]
...:
3.33 ms ± 235 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [70]: %timeit ms[500] = ord('a')
73.6 ns ± 0.433 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [71]: %%timeit v = list(data)
...: v[500] = 'a'
...:
28.7 ns ± 0.144 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [72]: sys.getsizeof(data)
Out[72]: 4194380
In [73]: sys.getsizeof(ms)
Out[73]: 4456524
In [74]: sys.getsizeof(list(data))
Out[74]: 9437296
变换列表很简单,比变异数组快3倍,而且只使用了2倍的内存。
答案 1 :(得分:0)
Python3中的替换是str,内置类型。字符串是 Unicode 代码点的不可变序列。
因此,无需使用array('u', ...)
,str
就足够了。
顺便说一下,删除'u'
(在内部使用PyUnicode*
)的原因是Py_UNICODE*
表示被弃用且效率低下;在性能或内存敏感的情况下应该避免使用它。
答案 2 :(得分:0)
Python 3.3+已经不再单独使用Unicode了。因为PEP393,这就是为什么一切都可以表达并用作str。
Here如何处理后Python 3.3解释器中的Unicode处理。根据定义 -
Unicode标准描述了代码如何表示字符 点。代码点是整数值,通常用16表示。 在标准中,使用符号U + 12CA来编写代码点 表示值为0x12ca(十进制4,810)的字符。 Unicode 标准包含很多列出字符及其表的表 相应的代码点:
最后,我不确定你想要达到什么目标,但是以下是否可以完成这项工作?
ins = "Aéí"
m = "ä" + ins[1:]
print(m)
在Python 3.5.2版本中,它为我提供了这个输出 -
äéí
如果有帮助,请告诉我
最后请注意,如果您想知道+
运算符,那么here就是一个很好的SO帖子。投票最多的答案的要点是:如果您使用的是Cpython,最好使用+
而不是append
join
等。
如果您想使用您的apprach,仍然有整个阵列模块available,其中包含您运行我们的代码所需的所有内容。我在python3.5中进行了测试,但它确实有效。
也有这种方式 -
a = "ä"
p = b"".join([a.encode('utf-8'), ins[1:].encode('utf-8')])
print(p.decode('utf-8'))