问题描述
前两天遇到一个很奇怪的问题,本来我想用python的zip
函数实现如下的效果:
a = [1, 2, 3, 4, 5]
b = ['a', 'b', 'c', 'd', 'e']
c = ['one', 'two', 'three', 'four', 'five']
# 然后把a b c打包成
# [(1, 'a', 'one'), (2, 'b', 'two'), (3, 'c', 'three'), (4, 'd', 'four'), (5, 'e', 'five')]
由于某些原因,我的列表使用了[a, b, c]
这样的格式进行了存储,假设combine_list = [a, b, c]
,这里的a
b
c
是上面的三个列表,因此我得到了一个嵌套列表combine_list
,然后我使用了list(zip(combine_list))
,希望能得到以上结果,但却得到了:
[([1, 2, 3, 4, 5],), (['a', 'b', 'c', 'd', 'e'],), (['one', 'two', 'three', 'four', 'five'],)]
解决方法
呃呃,这个问题卡了我老半天,最后debug才发现问题出在这…于是我更改了使用方式,采用了list(zip(a,b,c))
,成功得到了上述结果。应该是因为我把它们写成了一个列表,因此zip直接对这个列表进行了打包,我以前从没注意过这个问题…
如果还是想要用combine_list
作为参数,比如我并不知道里边所有列表的名称,怎么办呢?也可以把*
放在参数前面,意为解压操作,即list(zip(*combine_list))
:
list(zip(*combine_list))
# [(1, 'a', 'one'), (2, 'b', 'two'), (3, 'c', 'three'), (4, 'd', 'four'), (5, 'e', 'five')]
好弱智的问题呃呃,看来我写程序的时候根本没带脑子
无聊的问题背景
写信息论课设时,需要以列表的形式存储图像的像素然后进行存储,对于PIL来说,使用np.asarray(Image.open(filename))
读取一张RGB图得到的结果是这样的:
array([[[101, 0, 0],
[140, 0, 142],
[151, 0, 146],
...,
[192, 0, 158],
[205, 0, 177],
[120, 0, 181]],
...,
[166, 199, 150],
[171, 205, 181],
[198, 200, 171]]], dtype=uint8)
其中每个最内层的列表的三个元素分别代表了某个坐标的R, G, B值,如果把Red代表的像素全部放在一起:
[101, 140, 151, ... , 192, 205, 120, ... ,166, 171, 198]
这样就会得到一个列表,关键问题在于,这样的排列方式对于编码很有用,如果按照
R
1
G
1
B
1
,
R
2
G
2
B
2
R_1G_1B_1, R_2G_2B_2
R1G1B1,R2G2B2的方式排列像素,会非常不适合类似游程编码的编码方式的进行,大幅度降低编码效率,因此我尝试了把所有的RGB分别放在一个列表里,三个列表再组成一个列表,这样的话直接以组合的列表作为参数进行zip,进而转换成Image.fromarray()
所需要的array格式会很方便,也同样适合不知道列表中有多少通道时直接打包