列表压平的实现
对于以下这种输入输出关系,我们称之为列表的压平
input: li = [[[[[1], 2], 3], 4], 5]
output: [1, 2, 3, 4, 5]
方法1:了解到一个递归的解法,很不错
def dig_lists(pram_list):
output = []
for e in pram_list:
if isinstance(e, list):
output += dig_lists(e)
else:
output.append(e)
return output
li = [[[[[1], 2], 3], 4], 5]
dig_lists(li)
>>>[1, 2, 3, 4, 5]
方法2:这个只能针对双层列表,且里面每一个都只能由单个元素,因为array()这里变成了数组,而非列表
import numpy as np
x = np.array([[1], [2], [3], [4], [5]])
y = x.reshape(1,-1)
z = np.squeeze(y)
print(x)
print(y)
print(z)
print(a)
>>>[[1]
[2]
[3]
[4]
[5]]
>>>[[1 2 3 4 5]]
>>>[1 2 3 4 5]
reshape()
- reshape()第一个小例子
arr = [1,2,3,4,5,6,7,8,9]
array = np.array(arr)
print(array.reshape(3,3)) # 使用reshape把该列表变成了3*3的矩阵
print(array.reshape(-1,3)) # 这个同样也可以变成3*3的矩阵,好神奇。why?
# 这是因为前面的-1代表不知道可以分多少行,但是需要分成三列。
- 第二个小例子
arr = [1,2,3,4,5,6,7,8]
array = np.array(arr)
print(array.reshape(2,2,2)) # 变为三维数组
- note: reshape新生成数组和原数组公用一个内存,不管改变哪个都会互相影响。
- 看到一个实际的例子
from sklearn.datasets import load_digits 一个图片的数据集
picture_data = data.reshape(-1,8,8,1)
这个图像的表示方法是1797*64,表示1797张图片,每张图片用一行64个数表示,要把这一行的数据取出来,就要用到到reshape;
-1表示不知道,两个8表示8行8列,1表示一维空间(彩色是在处理的时候是三维空间RGB),这句代码就是把179764这个矩阵,变换成88的不知道多少个的矩阵,这样后面就方便用CNN神经网络去处理了。
参考:https://blog.****.net/zenghaitao0128/article/details/78512715
squeeze()
- 作用:从数组的形状中删除单维度条目,即把shape中为1的维度去掉
- 语法:
numpy.squeeze(a,axis = None)
- a表示输入的数组,axis选择形状中的一维条目的子集。如果选择形状输入大于1的轴,则会引发错误。
- 场景:在机器学习和深度学习中,通常算法的结果是可以表示向量的数组(即包含两对或以上的方括号形式[[]]),如果直接利用这个数组进行画图可能显示界面为空(见后面的示例)。我们可以利用squeeze()函数将表示向量的数组转换为秩为1的数组,这样利用matplotlib库函数画图时,就可以正常的显示结果了。
x = np.array([[[0], [1], [2]]])
print(x.shape)
print(np.squeeze(x))
print(np.squeeze(x).shape)
print(np.squeeze(x, axis=0)) # 第0层是[[[0], [1], [2]]],他的子集是一个一维数组
print(np.squeeze(x,axis=0).shape)
print(np.squeeze(x, axis=2)) # 第2层[0], [1], [2],他的子集有三个,分别是一维数组
print(np.squeeze(x,axis=2).shape)
print(np.squeeze(x, axis=1)) # 第1层是[[0], [1], [2]],他的子集是一个三维维数组,会报错,此处就不返回了
print(np.squeeze(x,axis=1).shape)
>>>(1, 3, 1)
>>>[0 1 2]
>>>(3,)
>>>[[0]
[1]
[2]]
>>>(3, 1)
>>>[[0 1 2]]
>>>(1, 3)
- 图示
import matplotlib.pyplot as plt
import numpy as np
#无法正常显示图示案例
squares =np.array([[1,4,9,16,25]])
print(squares.shape) #要显示的数组为可表示1行5列的向量的数组
>>>(1, 5)
plt.plot(squares)
plt.show()
# 正常显示图示案例
# 通过np.squeeze()函数转换后,要显示的数组变成了秩为1的数组,即(5,)
plt.plot(np.squeeze(squares))
plt.show()
print(np.squeeze(squares).shape)
>>>(5,)
方法3:也是只能处理二层的
import itertools
a = ['a', 'b', ['c', ['d', 'e']]]
out = list(itertools.chain.from_iterable(a))
print(out)
>>>['a', 'b', 'c', ['d', 'e']]
itertools 也是一个库
参考: https://blog.****.net/pipisorry/article/details/45171451
https://blog.****.net/weixin_41084236/article/details/81626968?utm_source=blogxgwz4
- itertools.chain() 它接受一系列可迭代对象作为输入并返回一个新的迭代器(实际上是在对多个容器进行迭代),该迭代器可连续访问并返回提供的每个迭代对象中的元素
from itertools import chain
b = ['x', 'y', 'z']
test = chain('AB', '123', b)
for el in test:
print(el)
输出:
A
B
1
2
3
x
y
z
- 如果输入的序列很大,在内存使用上chain()就会高效很多,而且当可迭代对象之间不是同一种类型时也可以轻松适用。
- chain.from_iterable(iterables) 将单个iterable中的所有元素拼接输出。
d=['串一株幸运草',' 串一个同心圆']
for i in itertools.chain.from_iterable(d):
print(i)
输出:
串
一
株
幸
运
草
串
一
个
同
心
圆
方法4:sum()
a = [[1, 2], [3, 4], [5, 6]]
print(sum(a, []))
>>> [1, 2, 3, 4, 5, 6]
print(sum(a, [9,[10,11]]))
>>>[9, [10, 11], 1, 2, 3, 4, 5, 6]
- 语法:sum(iterable, start=None)
- 返回一个可迭代的数字(非字符串)加上参数’start’的值(默认为0)。 当iterable为空时,返回start。
方法5:直接用列表
a = [[1, 2], [3, 4], [5, 6]]
print([x for i in a for x in i])
>>> [1, 2, 3, 4, 5, 6]
a = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]
print([x for l1 in a for l2 in l1 for x in l2])
>>>[1, 2, 3, 4, 5, 6, 7, 8]
小结
暂时写到这里,如有不足,还请指正~