我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

本文主要说的是:python内的常见数据类型的for in遍历方法。目前常见的python数据类型都可以使用这个for in遍历,能单独成篇的主要原因,是在遍历中获得索引值index(或者简称为i)。

苏南大叔:python数据类型ndarray/list/set/tuple/dict,for in遍历方法总结 - for in 遍历
python数据类型ndarray/list/set/tuple/dict,for in遍历方法总结(图4-1)

苏南大叔的“程序如此灵动”技术博客,记录苏南大叔的代码经验总结。本文测试环境:win10,python@3110,numpy@ 1.24.2

数据类型转化

在前面的一系列文章中,大家可以知道:这些类数组的python数据类型dataframe/ndarray/list/set/tuple/dict,甚至string,都是可以相互转化的。

那么,对这些数据的遍历也是具有通性的。本文聚焦于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)

苏南大叔:python数据类型ndarray/list/set/tuple/dict,for in遍历方法总结 - 第一种遍历方法
python数据类型ndarray/list/set/tuple/dict,for in遍历方法总结(图4-2)

方案二: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

苏南大叔:python数据类型ndarray/list/set/tuple/dict,for in遍历方法总结 - 第二种遍历方法
python数据类型ndarray/list/set/tuple/dict,for in遍历方法总结(图4-3)

方案三: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

苏南大叔:python数据类型ndarray/list/set/tuple/dict,for in遍历方法总结 - 第三种遍历方法
python数据类型ndarray/list/set/tuple/dict,for in遍历方法总结(图4-4)

完整代码

如果考虑获得索引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代码文章总结,请点击:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   python