Python:list()不知何故就位了吗?

Python:list()不知何故就位了吗?,python,list,pandas,Python,List,Pandas,我在使用list()时发现了一个我不理解的订单依赖关系。我从一个zipmytup开始,测试了3个版本的代码,结果如下df_q是一个常规数据帧: #ver1 df_q.loc[list(mytup)] # first access works fine df_q.loc[list(mytup)] # TypeError: Cannot infer number of levels from empty list #ver2 list(mytup) df_q.loc[mytup] # TypeEr

我在使用
list()
时发现了一个我不理解的订单依赖关系。我从一个zip
mytup
开始,测试了3个版本的代码,结果如下
df_q
是一个常规数据帧:

#ver1
df_q.loc[list(mytup)] # first access works fine
df_q.loc[list(mytup)] # TypeError: Cannot infer number of levels from empty list

#ver2
list(mytup)
df_q.loc[mytup] # TypeError: object of type 'zip' has no len()
df_q.loc[mytup]

#ver3 works as excepted
mylist = list(mytup)
df_q.loc[mylist]
df_q.loc[mylist]

对我来说,由于我只在
ver1
中的第二次调用中收到一个错误,我最初认为
list()
有一些未记录的就地行为,但显然不是因为
ver2
不起作用
ver3
按预期工作,但我不明白1/2中发生了什么。

问题是
zip
返回一个zip对象,它是一个迭代器。大多数性能良好的迭代器都是单过程的:

>>> z = zip((1,2),('a','b'))
>>> z
<zip object at 0x10193a908>
>>> next(z)
(1, 'a')
>>> next(z)
(2, 'b')
>>> next(z)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> list(z)
[]
因此,如果您想重用压缩后的值,您需要保留对物化列表的引用,就像您在第三次尝试中所做的那样

需要明确的是,这不是特定于
list
函数的,而是针对在zip对象上迭代的任何对象:

>>> z = zip((1,2),('a','b'))
>>> d1 = dict(z)
>>> d2 = dict(z)
>>> d1
{1: 'a', 2: 'b'}
>>> d2
{}

谢谢,这很有道理!你能告诉我,如果我不想依次使用list(z)、dict(z),那么重置迭代器的合适方法是什么吗?@JohnSmith
zip
迭代器是单次的,大多数迭代器都是单次的。你不能重置它们。这使得它们的内存效率非常高,因此,如果您需要多次使用它们,就必须使用一些具体化的数据结构。或者只是重新创建zip对象。注意,我可能会做一些类似于
my_list=zip(x,y);my_dict=dict(my_list)
mytup
对于非元组的东西来说,是一个非常容易引起误解的名称。
>>> z = zip((1,2),('a','b'))
>>> d1 = dict(z)
>>> d2 = dict(z)
>>> d1
{1: 'a', 2: 'b'}
>>> d2
{}