Python列表推导式无法获取引用及train_test_split使用问题咨询
解决Python中获取列表元素引用并传递给train_test_split的问题
问题分析
你遇到的核心问题是Python的引用机制特性:当你用列表推导式从zip(x_train, x_test)里提取元素时,拿到的是x_train和x_test中每个元素当前的值(也就是你初始化的None),而不是指向x_train[i]或x_test[i]这些位置的"可修改引用"。所以后续想用*recv让train_test_split直接修改x_train和x_test的内容,自然行不通。
你的需求本质是:把x中的每个特征集拆分到对应的x_train[i]和x_test[i]里,同时希望能通过类似*recv的方式传递这些位置,让拆分结果直接赋值进去。
解决方案
方案1:直接拆分train_test_split的返回结果(最推荐)
没必要提前把x_train和x_test初始成全None的列表,直接调用train_test_split后,把返回的结果拆分到两个列表里就行,简单直接:
from sklearn.model_selection import train_test_split # 假设x是包含多个特征数组的列表(比如x = [X1, X2, X3]),y是目标变量 split_results = train_test_split(*x, y, test_size=0.2, random_state=42) # 拆分结果的结构是:[X1_train, X1_test, X2_train, X2_test, ..., y_train, y_test] x_train = split_results[0::2][:-1] # 步长2取所有训练集,最后去掉y_train x_test = split_results[1::2][:-1] # 步长2取所有测试集,最后去掉y_test y_train, y_test = split_results[-2:]
这种方式完全绕开了引用传递的坑,代码清晰易懂,维护起来也方便。
方案2:用可变容器模拟"可修改引用"(如果必须提前初始化)
如果你因为某些原因一定要提前创建x_train和x_test的结构,可以用单元素列表作为可变容器——因为列表是可变对象,修改它内部的元素会直接影响原列表:
from sklearn.model_selection import train_test_split # 初始化x_train和x_test为单元素列表的列表(每个元素是一个可变的"容器") x_train = [[] for _ in range(len(x))] x_test = [[] for _ in range(len(x))] # 构建recv,把每个x_train[i]和x_test[i]的容器加进去 recv = [] for train_slot, test_slot in zip(x_train, x_test): recv.append(train_slot) recv.append(test_slot) # 调用train_test_split拿到拆分结果 split_results = train_test_split(*x, y, test_size=0.2, random_state=42) # 把拆分结果塞进对应的容器里 for i in range(len(x)): recv[2*i][0] = split_results[2*i] # 修改train_slot的内部元素 recv[2*i+1][0] = split_results[2*i+1] # 修改test_slot的内部元素 # 最后可以把x_train和x_test转换成普通列表(如果需要的话) x_train = [slot[0] for slot in x_train] x_test = [slot[0] for slot in x_test] y_train, y_test = split_results[-2:]
为什么你的原代码不行?
在你写的代码里:
x_train = [None for _ in range(len(x))] x_test = [None for _ in range(len(x))] recv = [item for sublist in zip(x_train, x_test) for item in sublist]
recv里的每个item都是None的引用,而不是指向x_train[i]或x_test[i]这个位置的引用。当你尝试给item赋值时,只是让item指向了新的对象,但x_train[i]还是原来的None——这就是为什么你的方法没法修改原列表的原因。
内容的提问来源于stack exchange,提问作者Saravanabalagi Ramachandran
相关产品推荐
相关产品推荐

