python 空格分割分割列表怎么弄啊,没找到的

python中split实现字符串分割方法-python-Php教程-壹聚教程网python中split实现字符串分割方法
python中split函数是像php中的split函数一样可以实现字符串分割了,下面本文章主要是整理关于分割函数的使用例子,希望能给各位带来一些帮助。
1 str.split([seq [,maxsplit]])&& 我们最常用到的!
姓名,年龄|另外一个用户姓名,年龄
name:haha,age:20|name:,age:30|name:fef,age:55
那我们可以通过字符串对象的split方法切割字符串对象为列表。
a = 'name:haha,age:20|name:python,age:30|name:fef,age:55'
print a.split('|')
返回结果:
['name:haha,age:20', 'name:python,age:30', 'name:fef,age:55']
通过上面的介绍,相信你对python string split有一个比较好的了解
s='server=uid=database=pwd=secret'&
&&& s.split(&;&)&
[['server=mpilgrim', 'uid=sa', 'database=master', 'pwd=secret']]
如果你的分隔符是一个或者多个空格,那么你就不必给出任何参数,即直接使用str.split() 即可
&&& fly='bigzhu,&&&&&&&&& flyzhu'&
&&& fly.split()&
['bigzhu,', 'flyzhu']&
&&& fly='bigzhu,&&&&&&&&& flyzhu'&
&&& fly_list=fly.split()&
&&& print fly_list&
['bigzhu,', 'flyzhu']&
&&& fly=''.join(fly_list)&
&&& print fly&
bigzhu,flyzhu&
&&& fly.split(',')&
['bigzhu', 'flyzhu']
上一页: &&&&&下一页:相关内容博客访问: 1213684
博文数量: 180
博客积分: 3184
博客等级: 中校
技术积分: 3686
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: Python/Ruby
迭代多维数组是就第一个轴而言的:
>>> for row in b:
[10 11 12 13]
[20 21 22 23]
[30 31 32 33]
[40 41 42 43]
然而,如果一个人想对每个数组中元素进行运算,我们可以使用flat属性,该属性是数组元素的一个迭代器:
>>> for element in b.flat:
print element,
0 1 2 3 10 11 12 13 20 21 22 23 30 31 32 33 40 41 42 43
更多[], …, newaxis, ndenumerate, indices, index exp 参考
更改数组的形状
一个数组的形状由它每个轴上的元素个数给出:
>>> a = floor(10*random.random((3,4)))
array([[ 7.,
>>> a.shape
一个数组的形状可以被多种命令修改:
>>> a.ravel() # flatten the array
array([ 7.,
>>> a.shape = (6, 2)
>>> a.transpose()
array([[ 7.,
由ravel()展平的数组元素的顺序通常是“C风格”的,就是说,最右边的索引变化得最快,所以元素a[0,0]之后是a[0,1]。如果数组被改变形状(reshape)成其它形状,数组仍然是“C风格”的。NumPy通常创建一个以这个顺序保存数据的数组,所以ravel()将总是不需要复制它的参数。但是如果数组是通过切片其它数组或有不同寻常的选项时,它可能需要被复制。函数reshape()和ravel()还可以被同过一些可选参数构建成FORTRAN风格的数组,即最左边的索引变化最快。
reshape函数改变参数形状并返回它,而resize函数改变数组自身。
array([[ 7.,
>>> a.resize((2,6))
array([[ 7.,
如果在改变形状操作中一个维度被给做-1,其维度将自动被计算
更多 shape, reshape, resize, ravel 参考
组合(stack)不同的数组
几种方法可以沿不同轴将数组堆叠在一起:
>>> a = floor(10*random.random((2,2)))
array([[ 1.,
>>> b = floor(10*random.random((2,2)))
array([[ 3.,
>>> vstack((a,b))
array([[ 1.,
>>> hstack((a,b))
array([[ 1.,
函数column_stack以列将一维数组合成二维数组,它等同与vstack对一维数组。
>>> column_stack((a,b))
# With 2D arrays
array([[ 1.,
>>> a=array([4.,2.])
>>> b=array([2.,8.])
>>> a[:,newaxis]
# This allows to have a 2D columns vector
array([[ 4.],
>>> column_stack((a[:,newaxis],b[:,newaxis]))
array([[ 4.,
>>> vstack((a[:,newaxis],b[:,newaxis])) # The behavior of vstack is different
array([[ 4.],
row_stack函数,另一方面,将一维数组以行组合成二维数组。
对那些维度比二维更高的数组,hstack沿着第二个轴组合,vstack沿着第一个轴组合,concatenate允许可选参数给出组合时沿着的轴。
在复杂情况下,r_[]和c_[]对创建沿着一个方向组合的数很有用,它们允许范围符号(“:”):
>>> r_[1:4,0,4]
array([1, 2, 3, 0, 4])
当使用数组作为参数时,r_和c_的默认行为和vstack和hstack很像,但是允许可选的参数给出组合所沿着的轴的代号。
更多函数hstack , vstack, column_stack , row_stack , concatenate , c_ , r_ 参见.
将一个数组分割(split)成几个小数组
使用hsplit你能将数组沿着它的水平轴分割,或者指定返回相同形状数组的个数,或者指定在哪些列后发生分割:
>>> a = floor(10*random.random((2,12)))
array([[ 8.,
>>> hsplit(a,3)
# Split a into 3
[array([[ 8.,
9.]]), array([[ 0.,
5.]]), array([[ 0.,
>>> hsplit(a,(3,4))
# Split a after the third and the fourth column
[array([[ 8.,
2.]]), array([[ 9.],
[ 9.]]), array([[ 0.,
vsplit沿着纵向的轴分割,array split允许指定沿哪个轴分割。
复制和视图
当运算和处理数组时,它们的数据有时被拷贝到新的数组有时不是。这通常是新手的困惑之源。这有三种情况:
完全不拷贝
简单的赋值不拷贝数组对象或它们的数据。
>>> a = arange(12)
# no new object is created
>>> b is a
# a and b are two names for the same ndarray object
>>> b.shape = 3,4
# changes the shape of a
>>> a.shape
Python 传递不定对象作为参考,所以函数调用不拷贝数组。
>>> def f(x):
print id(x)
# id is a unique identifier of an object
视图(view)和浅复制
不同的数组对象分享同一个数据。视图方法创造一个新的数组对象指向同一数据。
>>> c = a.view()
>>> c is a
>>> c.base is a
# c is a view of the data owned by a
>>> c.flags.owndata
>>> c.shape = 2,6
# a's shape doesn't change
>>> a.shape
>>> c[0,4] = 1234
# a's data changes
切片数组返回它的一个视图:
>>> s = a[ : , 1:3]
# spac could also be written "s = a[:,1:3]"
>>> s[:] = 10
# s[:] is a view of s. Note the difference between s=10 and s[:]=10
这个复制方法完全复制数组和它的数据。
>>> d = a.copy()
# a new array object with new data is created
>>> d is a
>>> d.base is a
# d doesn't share anything with a
>>> d[0,0] = 9999
函数和方法(method)总览
这是个NumPy函数和方法分类排列目录。这些名字链接到,你可以看到这些函数起作用。
arange, array, copy, empty, empty_like, eye, fromfile, fromfunction, identity, linspace, logspace, mgrid, ogrid, ones, ones_like, r , zeros, zeros_like
astype, atleast 1d, atleast 2d, atleast 3d, mat
array split, column stack, concatenate, diagonal, dsplit, dstack, hsplit, hstack, item, newaxis, ravel, repeat, reshape, resize, squeeze, swapaxes, take, transpose, vsplit, vstack
all, any, nonzero, where
argmax, argmin, argsort, max, min, ptp, searchsorted, sort
choose, compress, cumprod, cumsum, inner, fill, imag, prod, put, putmask, real, sum
cov, mean, std, var
基本线性代数
cross, dot, outer, svd, vdot
广播法则(rule)
广播法则能使通用函数有意义地处理不具有相同形状的输入。
广播第一法则是,如果所有的输入数组维度不都相同,一个“1”将被重复地添加在维度较小的数组上直至所有的数组拥有一样的维度。
广播第二法则确定长度为1的数组沿着特殊的方向表现地好像它有沿着那个方向最大形状的大小。对数组来说,沿着那个维度的数组元素的值理应相同。
应用广播法则之后,所有数组的大小必须匹配。更多细节可以从这个找到。
花哨的索引和索引技巧
NumPy比普通Python序列提供更多的索引功能。除了索引整数和切片,正如我们之前看到的,数组可以被整数数组和布尔数组索引。
通过数组索引
>>> a = arange(12)**2
# the first 12 square numbers
>>> i = array( [ 1,1,3,8,5 ] )
# an array of indices
# the elements of a at the positions i
array([ 1,
9, 64, 25])
>>> j = array( [ [ 3, 4], [ 9, 7 ] ] )
# a bidimensional array of indices
# the same shape as j
array([[ 9, 16],
[81, 49]])
当被索引数组a是多维的时,每一个唯一的索引数列指向a的第一维[^5]。以下示例通过将图片标签用调色版转换成色彩图像展示了这种行为。
>>> palette = array( [ [0,0,0],
[255,0,0],
[0,255,0],
[0,0,255],
[255,255,255] ] )
>>> image = array( [ [ 0, 1, 2, 0 ],
# each value corresponds to a color in the palette
[ 0, 3, 4, 0 ]
>>> palette[image]
# the (2,4,3) color image
[255, 255, 255],
我们也可以给出不不止一维的索引,每一维的索引数组必须有相同的形状。
>>> a = arange(12).reshape(3,4)
array([[ 0,
9, 10, 11]])
>>> i = array( [ [0,1],
# indices for the first dim of a
>>> j = array( [ [2,1],
# indices for the second dim
>>> a[i,j]
# i and j must have equal shape
array([[ 2,
[ 7, 11]])
>>> a[i,2]
array([[ 2,
[ 6, 10]])
>>> a[:,j]
# i.e., a[ : , j]
array([[[ 2,
[11, 11]]])
自然,我们可以把i和j放到序列中(比如说列表)然后通过list索引。
>>> l = [i,j]
# equivalent to a[i,j]
array([[ 2,
[ 7, 11]])
然而,我们不能把i和j放在一个数组中,因为这个数组将被解释成索引a的第一维。
>>> s = array( [i,j] )
# not what we want
---------------------------------------------------------------------------
IndexError
Traceback (most recent call last)
----> 1 a[s]
IndexError: index (3) out of range (0<=index>>
>>> a[tuple(s)]
# same as a[i,j]
array([[ 2,
[ 7, 11]])
另一个常用的数组索引用法是搜索时间序列最大值。
>>> time = linspace(20, 145, 5)
# time scale
>>> data = sin(arange(20)).reshape(5,4)
# 4 time-dependent series
array([[ 0.
[-0.7568025 , -0., -0.2794155 ,
0.6569866 ],
0., -0., -0.],
[-0., -0., -0.,
>>> ind = data.argmax(axis=0)
# index of the maxima for each series
array([2, 0, 3, 1])
>>> time_max = time[ ind]
# times corresponding to the maxima
>>> data_max = data[ind, xrange(data.shape[1])] # => data[ind[0],0], data[ind[1],1]...
>>> time_max
>>> data_max
array([ 0.,
0.6569866 ])
>>> all(data_max == data.max(axis=0))
你也可以使用数组索引作为目标来赋值:
>>> a = arange(5)
array([0, 1, 2, 3, 4])
>>> a[[1,3,4]] = 0
array([0, 0, 2, 0, 0])
然而,当一个索引列表包含重复时,赋值被多次完成,保留最后的值:
>>> a = arange(5)
>>> a[[0,0,2]]=[1,2,3]
array([2, 1, 3, 3, 4])
这足够合理,但是小心如果你想用Python的+=结构,可能结果并非你所期望:
>>> a = arange(5)
>>> a[[0,0,2]]+=1
array([1, 1, 3, 3, 4])
即使0在索引列表中出现两次,索引为0的元素仅仅增加一次。这是因为Python要求a+=1和a=a+1等同。
通过布尔数组索引
当我们使用整数数组索引数组时,我们提供一个索引列表去选择。通过布尔数组索引的方法是不同的我们显式地选择数组中我们想要和不想要的元素。
我们能想到的使用布尔数组的索引最自然方式就是使用和原数组一样形状的布尔数组。
>>> a = arange(12).reshape(3,4)
>>> b = a > 4
# b is a boolean with a's shape
array([[False, False, False, False],
[False, True, True, True],
[True, True, True, True]], dtype=bool)
# 1d array with the selected elements
array([ 5,
9, 10, 11])
这个属性在赋值时非常有用:
>>> a[b] = 0
# All elements of 'a' higher than 4 become 0
array([[0, 1, 2, 3],
[4, 0, 0, 0],
[0, 0, 0, 0]])
你可以参考看看如何使用布尔索引来生成曼德博集合的图像。
第二种通过布尔来索引的方法更近似于整数索引;对数组的每个维度我们给一个一维布尔数组来选择我们想要的切片。
>>> a = arange(12).reshape(3,4)
>>> b1 = array([False,True,True])
# first dim selection
>>> b2 = array([True,False,True,False])
# second dim selection
>>> a[b1,:]
# selecting rows
array([[ 4,
9, 10, 11]])
# same thing
array([[ 4,
9, 10, 11]])
>>> a[:,b2]
# selecting columns
array([[ 0,
[ 8, 10]])
>>> a[b1,b2]
# a weird thing to do
array([ 4, 10])
注意一维数组的长度必须和你想要切片的维度或轴的长度一致,在之前的例子中,b1是一个秩为1长度为三的数组(a的行数),b2(长度为4)与a的第二秩(列)相一致。
ix_函数可以为了获得的结果而用来结合不同向量。例如,如果你想要用所有向量a、b和c元素组成的三元组来计算a+b*c:
>>> a = array([2,3,4,5])
>>> b = array([8,5,4])
>>> c = array([5,4,6,8,3])
>>> ax,bx,cx = ix_(a,b,c)
array([[[2]],
array([[[8],
array([[[5, 4, 6, 8, 3]]])
>>> ax.shape, bx.shape, cx.shape
((4, 1, 1), (1, 3, 1), (1, 1, 5))
>>> result = ax+bx*cx
>>> result
array([[[42, 34, 50, 66, 26],
[27, 22, 32, 42, 17],
[22, 18, 26, 34, 14]],
[[43, 35, 51, 67, 27],
[28, 23, 33, 43, 18],
[23, 19, 27, 35, 15]],
[[44, 36, 52, 68, 28],
[29, 24, 34, 44, 19],
[24, 20, 28, 36, 16]],
[[45, 37, 53, 69, 29],
[30, 25, 35, 45, 20],
[25, 21, 29, 37, 17]]])
>>> result[3,2,4]
>>> a[3]+b[2]*c[4]
你也可以实行如下简化:
def ufunc_reduce(ufct, *vectors):
vs = ix_(*vectors)
r = ufct.identity
for v in vs:
r = ufct(r,v)
然后这样使用它:
>>> ufunc_reduce(add,a,b,c)
array([[[15, 14, 16, 18, 13],
[12, 11, 13, 15, 10],
[11, 10, 12, 14,
[[16, 15, 17, 19, 14],
[13, 12, 14, 16, 11],
[12, 11, 13, 15, 10]],
[[17, 16, 18, 20, 15],
[14, 13, 15, 17, 12],
[13, 12, 14, 16, 11]],
[[18, 17, 19, 21, 16],
[15, 14, 16, 18, 13],
[14, 13, 15, 17, 12]]])
这个reduce与ufunc.reduce(比如说add.reduce)相比的优势在于它利用了广播法则,避免了创建一个输出大小乘以向量个数的参数数组。
用字符串索引
继续前进,基本线性代数包含在这里。
简单数组运算
参考numpy文件夹中的linalg.py获得更多信息
>>> from numpy import *
>>> from numpy.linalg import *
>>> a = array([[1.0, 2.0], [3.0, 4.0]])
>>> print a
>>> a.transpose()
array([[ 1.,
>>> inv(a)
array([[-2. ,
[ 1.5, -0.5]])
>>> u = eye(2) # unit 2x2 "eye" represents "I"
array([[ 1.,
>>> j = array([[0.0, -1.0], [1.0, 0.0]])
>>> dot (j, j) # matrix product
array([[-1.,
[ 0., -1.]])
>>> trace(u)
>>> y = array([[5.], [7.]])
>>> solve(a, y)
array([[-3.],
>>> eig(j)
(array([ 0.+1.j,
array([[ 0..j,
Parameters:
square matrix
The eigenvalues, each repeated according to its multiplicity.
The normalized (unit "length") eigenvectors, such that the
column ``v[:,i]`` is the eigenvector corresponding to the
eigenvalue ``w[i]`` .
这是一个关于矩阵类的简短介绍。
>>> A = matrix('1.0 2.0; 3.0 4.0')
>>> type(A)
# file where class is defined
# transpose
>>> X = matrix('5.0 7.0')
>>> Y = X.T
>>> print A*Y
# matrix multiplication
>>> print A.I
[ 1.5 -0.5]]
>>> solve(A, Y)
# solving linear equation
matrix([[-3.],
索引:比较矩阵和二维数组
注意NumPy中数组和矩阵有些重要的区别。NumPy提供了两个基本的对象:一个N维数组对象和一个通用函数对象。其它对象都是建构在它们之上的。特别的,矩阵是继承自NumPy数组对象的二维数组对象。对数组和矩阵,索引都必须包含合适的一个或多个这些组合:整数标量、省略号(ellipses)、整数列表;布尔值,整数或布尔值构成的元组,和一个一维整数或布尔值数组。矩阵可以被用作矩阵的索引,但是通常需要数组、列表或者其它形式来完成这个任务。
像平常在Python中一样,索引是从0开始的。传统上我们用矩形的行和列表示一个二维数组或矩阵,其中沿着0轴的方向被穿过的称作行,沿着1轴的方向被穿过的是列。
让我们创建数组和矩阵用来切片:
>>> A = arange(12)
array([ 0,
9, 10, 11])
>>> A.shape = (3,4)
>>> M = mat(A.copy())
>>> print type(A),"
>>> print A
>>> print M
现在,让我们简单的切几片。基本的切片使用切片对象或整数。例如,A[:]和M[:]的求值将表现得和Python索引很相似。然而要注意很重要的一点就是NumPy切片数组不创建数据的副本;切片提供统一数据的视图。
>>> print A[:]; print A[:].shape
>>> print M[:]; print M[:].shape
现在有些和Python索引不同的了:你可以同时使用逗号分割索引来沿着多个轴索引。
>>> print A[:,1]; print A[:,1].shape
>>> print M[:,1]; print M[:,1].shape
注意最后两个结果的不同。对二维数组使用一个冒号产生一个一维数组,然而矩阵产生了一个二维矩阵。例如,一个M[2,:]切片产生了一个形状为(1,4)的矩阵,相比之下,一个数组的切片总是产生一个最低可能维度的数组。例如,如果C是一个三维数组,C[...,1]产生一个二维的数组而C[1,:,1]产生一个一维数组。从这时开始,如果相应的矩阵切片结果是相同的话,我们将只展示数组切片的结果。
假如我们想要一个数组的第一列和第三列,一种方法是使用列表切片:
>>> A[:,[1,3]]
array([[ 1,
[ 9, 11]])
稍微复杂点的方法是使用take()方法(method):
>>> A[:,].take([1,3],axis=1)
array([[ 1,
[ 9, 11]])
如果我们想跳过第一行,我们可以这样:
>>> A[1:,].take([1,3],axis=1)
array([[ 5,
[ 9, 11]])
或者我们仅仅使用A[1:,[1,3]]。还有一种方法是通过矩阵向量积(叉积)。
>>> A[ix_((1,2),(1,3))]
array([[ 5,
[ 9, 11]])
为了读者的方便,在次写下之前的矩阵:
>>> A[ix_((1,2),(1,3))]
array([[ 5,
[ 9, 11]])
现在让我们做些更复杂的。比如说我们想要保留第一行大于1的列。一种方法是创建布尔索引:
>>> A[0,:]>1
array([False, False, True, True], dtype=bool)
>>> A[:,A[0,:]>1]
array([[ 2,
[10, 11]])
就是我们想要的!但是索引矩阵没这么方便。
>>> M[0,:]>1
matrix([[False, False, True, True]], dtype=bool)
>>> M[:,M[0,:]>1]
matrix([[2, 3]])
这个过程的问题是用“矩阵切片”来切片产生一个矩阵,但是矩阵有个方便的A属性,它的值是数组呈现的。所以我们仅仅做以下替代:
>>> M[:,M.A[0,:]>1]
matrix([[ 2,
[10, 11]])
如果我们想要在矩阵两个方向有条件地切片,我们必须稍微调整策略,代之以:
>>> A[A[:,0]>2,A[0,:]>1]
array([ 6, 11])
>>> M[M.A[:,0]>2,M.A[0,:]>1]
matrix([[ 6, 11]])
我们需要使用向量积ix_:
>>> A[ix_(A[:,0]>2,A[0,:]>1)]
array([[ 6,
[10, 11]])
>>> M[ix_(M.A[:,0]>2,M.A[0,:]>1)]
matrix([[ 6,
[10, 11]])
技巧和提示
下面我们给出简短和有用的提示。
“自动”改变形状
更改数组的维度,你可以省略一个尺寸,它将被自动推导出来。
>>> a = arange(30)
>>> a.shape = 2,-1,3
# -1 means "whatever is needed"
>>> a.shape
array([[[ 0,
[ 9, 10, 11],
[12, 13, 14]],
[[15, 16, 17],
[18, 19, 20],
[21, 22, 23],
[24, 25, 26],
[27, 28, 29]]])
向量组合(stacking)
我们如何用两个相同尺寸的行向量列表构建一个二维数组?在MATLAB中这非常简单:如果x和y是两个相同长度的向量,你仅仅需要做m=[x;y]。在NumPy中这个过程通过函数column_stack、dstack、hstack和vstack来完成,取决于你想要在那个维度上组合。例如:
x = arange(0,10,2)
# x=([0,2,4,6,8])
y = arange(5)
# y=([0,1,2,3,4])
m = vstack([x,y])
# m=([[0,2,4,6,8],
[0,1,2,3,4]])
xy = hstack([x,y])
# xy =([0,2,4,6,8,0,1,2,3,4])
二维以上这些函数背后的逻辑会很奇怪。
参考并且在这里添加你的新发现: )
直方图(histogram)
NumPy中histogram函数应用到一个数组返回一对变量:直方图数组和箱式向量。注意:matplotlib也有一个用来建立直方图的函数(叫作hist,正如matlab中一样)与NumPy中的不同。主要的差别是pylab.hist自动绘制直方图,而numpy.histogram仅仅产生数据。
import numpy
import pylab
# Build a vector of 10000 normal deviates with variance 0.5^2 and mean 2
mu, sigma = 2, 0.5
v = numpy.random.normal(mu,sigma,10000)
# Plot a normalized histogram with 50 bins
pylab.hist(v, bins=50, normed=1)
# matplotlib version (plot)
pylab.show()
# Compute the histogram with numpy and then plot it
(n, bins) = numpy.histogram(v, bins=50, normed=True)
# NumPy version (no plot)
pylab.plot(.5*(bins[1:]+bins[:-1]), n)
pylab.show()
阅读(52515) | 评论(0) | 转发(7) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。出处:http://simple-/
其实早就打算写相关文章的,但因为抽不出时间还是一直没动笔。最近又想起来,然后翻开近半年前的草稿一看,居然一字未动。现在回想起来,当初定的目标似乎太遥远了,所以我打算把原来准备一次写完的内容拆成一小段一小段来写。这样有空就写一小段,似乎更实际一点。
在开始读这篇心得前,本人假定你对Python语言已有足够的了解,并已能写一些小程序;清楚游戏字库特别是图片类字库的原理、构造、作用,已做过或有充分准备可以制作一种字库。对于文章中出现的一些库和模块的功能,我会进行一定程度的讲解,更多需要你自行查阅。
1、你需要安装python 2.7.x(目前我使用2.7.2),可以在这里找到:
2、安装PIL(python的一个第三方图像处理库),当前最新版是1.1.7,,最新版本在此查看:
3、NVIDIA Texture Tools,可以将其他格式图片转换为dds格式,而且效率较高,还支持很多选项。但不单独提供,这是我提取出来的版本。
4、[可选]本人制作的字库生成器,你也可以使用其他类似软件代替,但本篇中提到字库生成器都以此为准。
5、urfFontReader(Urf字库生成器字体读取脚本)。很多例子都会用到,(记得点download)
转换bmp至png格式
字库生成的方法参考字库生成器的文章,这里不再详述。
由于字库生成器生成的bmp图片不方便接下来的操作,而且文件相对较大,所以推荐转换为png格式保存。png格式可以包含透明层,体积也很小,而且读取速度不慢。假设生成的图片为“1.bmp”,然后看下面的代码:
import Image #导入PIL的基本处理模块
#打开bmp文件并转换为RGBA模式
bmp = Image.open(&#39;1.bmp&#39;).convert(&#39;RGBA&#39;)
#用一个列表保存像素数据
#将所有像素用简单公式转换为灰度作为透明层,底图使用白色
for pix in bmp.getdata():
rgba.append((255, 255 ,255 ,int( pix[0]*0.299 + pix[1]*0.587 + pix[2]*0.114 )))
bmp.putdata(rgba)
bmp.save(&#39;1.png&#39;)
以上代码可以稍加修改,然后将此脚本作为一个命令行工具使用。
读取字体数据
我提供的urfFontReader可以很方便的读出保存在bin文件中的字体信息。这样就可以将相关数据转换为游戏需要的格式。下面通过分析该脚本的代码,初步了解二进制数据的处理方法。
#从struct模块引入必要函数
from struct import pack,unpack
def ReadUrfFontInfo(fontname):
#以二进制模式打开文件并读取
fl=open(fontname+&#39;.bin&#39;,&#39;rb&#39;)
#解开文件头中的数据
img_w,img_h,nums,ch,stp1,stp2=unpack(&#39;6i&#39;,fl.read(24))
#解开所有字符数据
data = unpack(&#39;=&#39;+&#39;H4i&#39;*nums,fl.read(-1)) #+’=&#39;使之采用标准数据大小
#用一个字典保存字符数据,方便使用
#转换成字典
for i in xrange(nums):
c,w,h,x,y = data[i*5:i*5+5]
db[c]=(w,h,x,y)
return (img_w,img_h,nums,ch),db
整个脚本主要使用了struct模块的upack函数来解构二进制数据。因为python并不能直接处理二进制数据(虽然可以当作字符串来处理,当其他数据类型就另当别论了)。upack函数的第一个参数用来描述数据结构,第二个参数是以字符串形式保存的数据。因为我这个字库当初设计得很简单,所以只用到二中类型,分别是:“H”无符号短整数;“i”有符号整数。与C程序中相应类型对应。
关于struct模块的更详细信息可以在网上搜索相关例程,或者在python控制台用help函数查看内部文档,之后不再详述。
下面是一个从其他脚本调用urfFontReader的实例。
#直接导入所需函数
from urfFontReader import ReadUrfFontInfo
#使用该函数读取字体bin文件,返回值分别存入等号前的变量
(img_w,img_h,nums,ch),font_data = ReadUrfFontInfo(r&#39;mydir\myfont&#39;)
#打印图片的宽、高,包含的字符数和字符默认高度
print &&&image : %dx%d
number of chars : %d
general height : %d&&&%(img_w,img_h,nums,ch)
#打印所有字符数据(unicode代码、宽、高、坐标x、y)
for char in font_data:
w,h,x,y=font_data[char]
print &X&%char,x,y,w,h
转换数据为游戏所需格式
字库生成器为了通用性,所以设计上是输出部分关键数据,然后根据具体游戏再转换为对应格式。
以下以相对较为简单的Chrome4引擎为例。该引擎的字库使用纯文本定义,每个字符需要6个相关参数。具体如下:
Char( unicode值, 实际宽度, 左顶点x坐标, 左顶点y坐标, 右下顶点x坐标, 右下顶点y坐标 )
根据上面的定义,有些数据在读取后可以直接使用,而有些则需要进行计算。因此得到以下代码:
from urfFontReader import ReadUrfFontInfo
(img_w,img_h,nums,ch),font_data = ReadUrfFontInfo(r&#39;1&#39;)
#创建一个文件用于写入输出文件
fm = open(&#39;mid_28.fm&#39;,&#39;w&#39;)
#先写入游戏字库需要的基本信息
fm.write(&#39;&#39;&#39;Name(&mid&)
MapWidth(%d)
MapHeight(%d)
FontHeight(%d)
&#39;&#39;&#39;%(img_w,img_h,ch))
#遍历所有数据,写入每个字符的定义
for char,(w,h,x,y) in font_data.iteritems():
fm.write(&Char(%d, %d, %d, %d, %d, %d)\n&%(char, w, x, y, x+w, y+ch))
由于字典类型是没有顺序的,所以输出的文件会有点乱。但稍加改动就可以按unicode代码的顺序输出数据。
#先将所有项的列表保存到一个变量
data = font_data.items()
#对这个列表排序
data.sort()
#再通过排序后的列表输出
for char,(w,h,x,y) in data:
fm.write(&Char(%d, %d, %d, %d, %d, %d)\n&%(char, w, x, y, x+w, y+ch))
以上介绍了一个相对简单的,保存为游戏可用格式的例子。在以后的文章中我会提供更多更复杂的例子。
分割字库图片
有很多情况需要分割字库图片。比如对于一些老显卡,可能不支持以上的纹理大小,某些游戏只支持固定大小纹理等等。分割字库的思路很简单。先打开一个字库,然后将字符挨个复制到新大小的图片中,当装不下时就保存当前图片再新建另外一张图片。借助PIL库,很容易完成这个任务。
import Image
from urfFontReader import ReadUrfFontInfo
(img_w,img_h,nums,ch),font_data = ReadUrfFontInfo(r&#39;1&#39;)
#设置分割成多大
max_w = 512 #目标宽度
max_h = 512 #目标高度
#打开我们的字库图片
img_in = Image.open(&#39;1.png&#39;)
img_idx = 0 #图片序号/计数器
cx = 0 #在目标图片中的x坐标
cy = 0 #在目标图片中的y坐标
#新建一张图像用于输出
img_out = Image.new(&RGBA&,(max_w,max_h))
#遍历所有数据进行分割
for char,(w,h,x,y) in font_data.iteritems():
#如果下一个字符粘贴后超出目标宽度则切换到下一行
if cx + w & max_w:
cy += ch #换行
#如果余下高度不足容纳一个字符则新建另一张图片
if cy + ch & max_h:
cy = 0 #y坐标归零
img_out.save(&#39;s_d.png&#39;%img_idx) #保存当前图片
img_out = Image.new(&RGBA&,(max_w,max_h)) #新建另一张图片
img_idx += 1 #图片序号+1
cx = 0 #x坐标归零
#从原图复制指定字符到新图片(这里特意分为两步以便看得更清楚,实际只需一步)
box = img_in.crop((x,y,x+w,y+ch)) #复制原图的指定区域
img_out.paste(box,(cx,cy)) #粘贴到新图的当前位置
#这里可以插入保存字符信息的代码
#位置向前移动一个字符
#结束后保存未保存的图片
img_out.save(&#39;s_d.png&#39;%img_idx)
这里所用的 crop 方法需要提供一个“box”参数,这个参数实际是一个列表,里面需要依序提供矩形的左上顶点和右下顶点的x、y坐标,然后该方法返回一个image对象,里面保存着截取的内容,相当于复制图片中的选定区域。然后再用 paste 方法粘贴到指定位置。更多信息请参考PIL文档的imgae模块部分:
以上只是最基本的字库图片分割方法。有时实际要求要复杂得多,比如我要每个字符上下左右都留4像素的边要如何做呢?对此,我想我是没义务多做解释的是吧?
将图片转换为DDS格式
DDS是许多DX游戏常用的纹理格式。NVIDIA Texture Tools 可以将多数格式的图片转换为DDS格式。虽然python也有办法保存DDS格式,但目前的脚本压缩速度都实在太慢。
转换DDS主要用到的是nvcompress这个工具。用法如下:
$ nvcompress [options] infile [outfile]
详细参数表参考“NVIDIA_Texture_Tools_README.txt”。
这里介绍一下这个工具与脚本结合的方法。这是一个命令行工具,所以最简单的方法就是直接命令行调用。
以分割图片的代码为例:
import os #导入os库
#新建函数SaveDDS
def SaveDDS():
img_out.save(&#39;tmp.png&#39;) #保存一个临时文件
os.system(r&#39;..\nvtt\nvcompress.exe -nocuda -nomips -bc3 tmp.png s_d.dds&#39;%img_idx) #通过命令行调用nvcompress,注意路径
os.remove(&#39;tmp.png&#39;) #最后删除临时文件
#在需要保存图片的位置直接调用这个函数
这里保存的是一个普通的带透明层的dds图片。而不同游戏又有不同要求,可能需要你多加注意。
写在后面的话
之所以要使用脚本,其目的主要是为了快速实现我们的想法,方便地开发我们需要的工具。而执行效率并不是我们的主要目的,这点一定要记住。如果能兼顾效率的话当然最好,但如果为了追求效率而减慢了开发速度那就失去了使用脚本的意义了。
在微博上关注:
- 创新工场-途客圈
- 问天(北京)信息技术有限公司
- 创业公司
- 赛诺(武汉)技术有限公司
- 赛诺(武汉)技术有限公司
相关 [利用 python 制作] 推荐:
- cong - (jobs, news)
其实早就打算写相关文章的,但因为抽不出时间还是一直没动笔. 最近又想起来,然后翻开近半年前的草稿一看,居然一字未动. 现在回想起来,当初定的目标似乎太遥远了,所以我打算把原来准备一次写完的内容拆成一小段一小段来写. 这样有空就写一小段,似乎更实际一点. 在开始读这篇心得前,本人假定你对Python语言已有足够的了解,并已能写一些小程序;清楚游戏字库特别是图片类字库的原理、构造、作用,已做过或有充分准备可以制作一种字库.
- chuang - Initiative
dropbox定制优化CPython虚拟机,自己搞了个malloc调度算法. 那个 !!!111cos(0). 期待这次PyCon China 2011.
- 企业架构 - ITeye博客
原文地址: http://blog.csdn.net/xuyuefei1988/article/details/、下面网上收罗的资料初学者应该够用了,但对比IBM的Python 代码调试技巧:. IBM:包括 pdb 模块、利用 PyDev 和 Eclipse 集成进行调试、PyCharm 以及 Debug 日志进行调试:.
- Eric - python相关的python 教程和python 下载你可以在老王python里寻觅
之前给大家分享的python 多线程抓取网页,我觉的大家看了以后,应该会对python 抓取网页有个很好的认识,不过这个只能用python 来抓取到网页的源代码,如果你想用做python 下载文件的话,上面的可能就不适合你了,最近我在用python 做文件下载的时候就遇到这个问题了,不过最终得以解决,为了让大家以后碰过这个问题有更好的解决办法,我把代码发出来:.
- 互联网 - ITeye博客
@FileName:
@Author:xx@
@Create date:
@description:用一行文字概述模块或脚本,用句号结尾. 不影响编码的效率,不与大众习惯冲突.. 使代码的逻辑更清晰,更易于理解..
*所有的 Python 脚本文件都应在文件头标上如下标识或其兼容格式的标识.
- 阿里古古
http://blog.csdn.net/luckeryin/article/details/4477233】. 本文讨论在没有方便的IDE工具可用的情况下,使用pdb调试python程序. 例如,有模拟税收计算的程序:. debug_demo函数计算4500的入账所需的税收. 在需要插入断点的地方,加入红色部分代码:如果_DEBUG值为True,则在该处开始调试(加入_DEBUG的原因是为了方便打开/关闭调试).
- hama - Wow! Ubuntu
Dive Into Python 是一份很知名的 Python 入门教程,由 Mark Pilgrim 编写,用户可以免费获取电子版本,而中文版则由啄木鸟社区翻译发布 [ 英文版 / 中文版 ]. 前阵子,Mark Pilgrim 又发布了 《Dive into Python 3》,此版本的内容涵盖了 Python 3 及其与 Python 2 的区别.
- eastxing - 赖勇浩的编程私伙局
赖勇浩(). 今天在 simple- 看到一篇《Python 面试题集合》(http://simple-/news/596),里面有一些很好的试题,如“Python是如何进行类型转换的. ”,也有一些让人吐血的试题,如“Python如何实现单例模式.
- 月乾 - 赖勇浩
今天在 simple- 看到一篇《Python 面试题集合》(http://simple-/news/596),里面有一些很好的试题,如“Python是如何进行类型转换的. ”,也有一些让人吐血的试题,如“Python如何实现单例模式. 其他23种设计模式python如何实现.
- xin - 秀码趣 -
Kivy是一个可用以快速创建新颖用户界面应用的开源Python库,比如可以用它来创建多点触摸的应用程序,它具备跨平台特性,目前发行有Windows、MacOS、Linux以及Android版本. 作为一个开源框架,Kivy具备以下特性:A.百分百免费使用;B.基于 LGPL3协议 开源,对商业化应用友好;C.跨平台,支持Windows、MacOS、Linux以及Android;D.允许在不同的平台上运行同一套代码;E.稳定以及有完善的API文档;F.通过OpenGL ES 2.0对硬件进行加速;G.自然支持大部分的输入协议或者输入设备;H.基于Python的简单API……等等.
坚持分享优质有趣的原创文章,并保留作者信息和版权声明,任何问题请联系:@。

我要回帖

更多关于 python 分割 的文章

 

随机推荐