python数据类型ndarray/list/set/tuple/dict,for in遍历方法总结
发布于 作者:苏南大叔 来源:程序如此灵动~本文主要说的是:python
内的常见数据类型的for in
遍历方法。目前常见的python
数据类型都可以使用这个for in
遍历,能单独成篇的主要原因,是在遍历中获得索引值index
(或者简称为i
)。
苏南大叔的“程序如此灵动”技术博客,记录苏南大叔的代码经验总结。本文测试环境:win10
,python@3110
,numpy@ 1.24.2
。
数据类型转化
在前面的一系列文章中,大家可以知道:这些类数组的python
数据类型dataframe
/ndarray
/list
/set
/tuple
/dict
,甚至string
,都是可以相互转化的。
- https://newsn.net/say/ndarray-list.html
- https://newsn.net/say/python-tuple.html
- https://newsn.net/say/dataframe-ndarray.html
那么,对这些数据的遍历也是具有通性的。本文聚焦于for in
数据遍历,看看都有哪些方案可以对这些类数组数据进行遍历。
下面的是个对list
类型进行遍历的范例:
name = ["苏","南","大","叔"]
for x in name:
print(x) # 苏
# for k,v in name: # ValueError: not enough values to unpack (expected 2, got 1)
# print(k,v)
for x in enumerate(name):
print(x,type(x)) # (0, '苏') <class 'tuple'>
for k,v in enumerate(name):
print(k,v) # 0 苏
当然,在实际操作中,不同的数据类型的访问方式也存在着较大差异,具体可以参考文末代码。
方案一:普通的for...in
普通的for in
能遍历出每个数据成员,但是不能遍历出索引值。
name = ["苏","南","大","叔"]
for x in name:
print(x) # 苏
为了遍历出索引值,可以定义一个普通的类似i++
的数字类型,来代替这个索引。
name = ["苏","南","大","叔"]
i = 0
for x in name:
print(i,x) # 0,苏
i = i+1 # i++ 报错
如果试图像其它编程语言里面一样,写for k,v in
的话,就会得到下的类似错误提示信息:
for k,v in name: # ValueError: not enough values to unpack (expected 2, got 1)
print(k,v)
输出:
Traceback (most recent call last):
File "C:\Users\sunan\Desktop\test\py\t.py", line 21, in <module>
for k,v in name:
^^^
ValueError: not enough values to unpack (expected 2, got 1)
方案二:for...in range()
这里直接通过重组直接获得了数字索引。
name = ["苏","南","大","叔"]
for i in range(len(name)):
print(i, name[i]) # 0 苏
然尔对于非数字索引或者索引起始值不为0的情况,效果有限。
name = {"s":"苏","n":"南","d":"大","s2":"叔"}
print(name["s"]) # 苏
for i in range(len(name)):
print(i, name[i]) # KeyError: 0
方案三:for k,v in enumerate()【推荐】
name = ["苏","南","大","叔"]
for x in enumerate(name):
print(x,type(x)) # (0, '苏') <class 'tuple'>
name = ["苏","南","大","叔"]
for k,v in enumerate(name):
print(k,v) # 0 苏
对于dict
类型,kv值和想象的有些差异:
name = {"s":"苏","n":"南","d":"大","s2":"叔"}
print(name["s"]) # 苏
for i,k in enumerate(name):
print(i,k,name[k]) # 0 s 苏
for in <dict>
得到的并不是key,value
,而是index,key
。
完整代码
如果考虑获得索引key
的情况,就推荐使用enumerate()
这种方式,下面对这种方式展开讨论:
_str = "苏南大叔"
_list = ["苏", "南", "大", "叔"]
_tuple = ("苏", "南", "大", "叔")
_set = {"苏", "南", "大", "叔"}
_dict = {"s": "苏", "n": "南", "d": "大", "s2": "叔"}
_dict2 = {0: "苏", 1: "南", 2: "大", 3: "叔"}
import numpy as np
import pandas as pd
_ndarray = np.array(_list)
_dataframe = pd.DataFrame(_ndarray)
_dataframe2 = pd.DataFrame(
[
("虎子", 5, "dog"),
("老许", 3, "bird"),
("二赖子", 6, "fish"),
("老白", 8, "catty"),
("小黑", 10, "puppy"),
],
index=["a1", "a2", "a3", "a4", "a5"],
columns=("name", "age", "class"),
)
def out(target):
print(target, "\r\n", type(target), "\r\n")
if type(target) == set:
print("set无序,输出结果理论上每次不同", "\r")
print("\r#################\r")
print("方法一")
for x in target:
if type(target) == pd.DataFrame:
print(target[x])
elif type(target) == dict:
print(target[x])
else:
print(x) # 苏
print("\r#################\r")
print("方法二")
try:
if type(target) == pd.DataFrame:
for i in range(len(target.columns)):
print(i)
print(target.iloc[:, i]) # 0 苏
else:
for i in range(len(target)):
print(i, target[i]) # 0 苏
except Exception as err:
if type(target) == dict:
print("dict的索引可能不是从零开始的")
elif type(target) == set:
print("set无序,不支持下标访问")
else:
print("出错了", err)
print("\r#################\r")
print("方法三")
for k, v in enumerate(target):
if type(target) == dict:
print(k, v, target[v]) # 0 s 苏
elif type(target) == pd.DataFrame:
print(k, v) # 0 s
print(target[v]) # 苏
else:
print(k, v) # 0 苏
print("\r=================================\r")
out(_str)
out(_list)
out(_tuple)
out(_set)
out(_dict)
out(_dict2)
out(_ndarray)
out(_dataframe)
out(_dataframe2)
输出:
苏南大叔
<class 'str'>
#################
方法一
苏
南
大
叔
#################
方法二
0 苏
1 南
2 大
3 叔
#################
方法三
0 苏
1 南
2 大
3 叔
['苏', '南', '大', '叔']
<class 'list'>
#################
方法一
苏
南
大
叔
#################
方法二
0 苏
1 南
2 大
3 叔
#################
方法三
0 苏
1 南
2 大
3 叔
('苏', '南', '大', '叔')
<class 'tuple'>
#################
方法一
苏
南
大
叔
#################
方法二
0 苏
1 南
2 大
3 叔
#################
方法三
0 苏
1 南
2 大
3 叔
{'苏', '大', '叔', '南'}
<class 'set'>
set无序,输出结果理论上每次不同
#################
方法一
苏
大
叔
南
#################
方法二
set无序,不支持下标访问
#################
方法三
0 苏
1 大
2 叔
3 南
{'s': '苏', 'n': '南', 'd': '大', 's2': '叔'}
<class 'dict'>
#################
方法一
苏
南
大
叔
#################
方法二
dict的索引可能不是从零开始的
#################
方法三
0 s 苏
1 n 南
2 d 大
3 s2 叔
{0: '苏', 1: '南', 2: '大', 3: '叔'}
<class 'dict'>
#################
方法一
苏
南
大
叔
#################
方法二
0 苏
1 南
2 大
3 叔
#################
方法三
0 0 苏
1 1 南
2 2 大
3 3 叔
['苏' '南' '大' '叔']
<class 'numpy.ndarray'>
#################
方法一
苏
南
大
叔
#################
方法二
0 苏
1 南
2 大
3 叔
#################
方法三
0 苏
1 南
2 大
3 叔
0
0 苏
1 南
2 大
3 叔
<class 'pandas.core.frame.DataFrame'>
#################
方法一
0 苏
1 南
2 大
3 叔
Name: 0, dtype: object
#################
方法二
0
0 苏
1 南
2 大
3 叔
Name: 0, dtype: object
#################
方法三
0 0
0 苏
1 南
2 大
3 叔
Name: 0, dtype: object
name age class
a1 虎子 5 dog
a2 老许 3 bird
a3 二赖子 6 fish
a4 老白 8 catty
a5 小黑 10 puppy
<class 'pandas.core.frame.DataFrame'>
#################
方法一
a1 虎子
a2 老许
a3 二赖子
a4 老白
a5 小黑
Name: name, dtype: object
a1 5
a2 3
a3 6
a4 8
a5 10
Name: age, dtype: int64
a1 dog
a2 bird
a3 fish
a4 catty
a5 puppy
Name: class, dtype: object
#################
方法二
0
a1 虎子
a2 老许
a3 二赖子
a4 老白
a5 小黑
Name: name, dtype: object
1
a1 5
a2 3
a3 6
a4 8
a5 10
Name: age, dtype: int64
2
a1 dog
a2 bird
a3 fish
a4 catty
a5 puppy
Name: class, dtype: object
#################
方法三
0 name
a1 虎子
a2 老许
a3 二赖子
a4 老白
a5 小黑
Name: name, dtype: object
1 age
a1 5
a2 3
a3 6
a4 8
a5 10
Name: age, dtype: int64
2 class
a1 dog
a2 bird
a3 fish
a4 catty
a5 puppy
Name: class, dtype: object
题外话
方案三中的灵魂函数enumerate()
,具有第二个参数,可以指定凭空幻化成来的key的起始值。目前来看,好像没有什么用。
_list = ["苏", "南", "大", "叔"]
for k, v in enumerate(_list, 110):
print(k, v)
输出:
110 苏
111 南
112 大
113 叔
dict的item()遍历
比如在词频统计中,最常见的dict
类型变量:
_dict = {"苏南":5,"大叔":8}
for key,value in _dict.items():
print(key,value) # 苏南 5
总结
可见:在对常见数据类型进行遍历时,为了同时获得索引,需要对代码进行一定的修改才行。直接试图强制遍历的话,就可能获得各种错误提示信息了。
更多苏南大叔的python
代码文章总结,请点击:
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。