Python 在for-in循环期间追加到元组
我需要在Python 在for-in循环期间追加到元组,python,iterator,tuples,Python,Iterator,Tuples,我需要在for in循环期间修改元组,以便迭代器对元组进行迭代 据我理解,元组是不可变的;因此tup=tup+(添加)只是重新分配tup,而不是更改原始的tup。所以这很棘手 下面是一个测试脚本: tup = ({'abc': 'a'}, {'2': '2'}) blah = True to_add = {'goof': 'abcde'} for i in tup: if blah: tup = tup + (to_add,) blah = False
for in
循环期间修改元组,以便迭代器对元组进行迭代
据我理解,元组是不可变的;因此tup=tup+(添加)
只是重新分配tup
,而不是更改原始的tup。所以这很棘手
下面是一个测试脚本:
tup = ({'abc': 'a'}, {'2': '2'})
blah = True
to_add = {'goof': 'abcde'}
for i in tup:
if blah:
tup = tup + (to_add,)
blah = False
print(i)
其中打印:
{'abc': 'a'}
{'2': '2'}
我想让它打印:
{'abc': 'a'}
{'2': '2'}
{'goof': 'abcde'}
据我所知,我需要“重新指向”隐式元组迭代器mid脚本,以便它指向新的元组。(我知道这是一件非常令人讨厌的事情)
此脚本访问相关的元组生成器:
import gc
tup = ({'abc': 'a'}, {'2': '2'})
blah = True
to_add = {'goof': 'abcde'}
for i in tup:
if blah:
tup = tup + (to_add,)
blah = False
refs = gc.get_referrers(i)
for ref in refs:
if type(ref) == tuple and ref != tup:
refs_to_tup = gc.get_referrers(ref)
for j in refs_to_tup:
if str(type(j)) == "<class 'tuple_iterator'>":
tuple_iterator = j
print(i)
导入gc
tup=({'abc':'a'},{'2':'2'})
胡说八道
to_add={'goof':'abcde'}
对于tup中的i:
如果是废话:
tup=tup+(要添加,)
废话
refs=gc.get\u referers(i)
参考文献中的参考文献:
如果类型(ref)=元组和ref!=tup:
refs\u to\u tup=gc.get\u referers(ref)
对于参考图中的j:
如果str(类型(j))==“”:
元组迭代器=j
印刷品(一)
如何修改这个tuple_生成器,使其指向新的tup,而不是旧的tup?这可能吗
我意识到这是一个非常奇怪的情况,我无法更改
tup
是一个元组,或者我需要在中使用隐式,因为我试图插入我无法更改的代码。因为您计划在循环中修改元组,您最好使用while循环来跟踪当前索引,而不是依赖迭代器。迭代器仅适用于循环遍历循环中未添加/删除到的集合
如果运行下面的示例,则生成的tup对象将添加项,同时循环3次
tup = ({'abc': 'a'}, {'2': '2'})
blah = True
to_add = {'goof': 'abcde'}
i = 0
while i < len(tup):
cur = tup[i]
if blah:
tup = tup + (to_add,)
blah = False
i += 1
print(tup)
tup=({'abc':'a'},{'2':'2'})
胡说八道
to_add={'goof':'abcde'}
i=0
而我
即使通过元组迭代器
对象的未记录内部,也无法在CPython中以可移植或特定的方式从Python中执行您试图执行的操作。元组引用存储在一个不向Python公开的变量中,并且(与存储的索引不同)不被\uuuu setstate\uuuu>或任何其他方法修改
然而,如果您愿意在CPython的背后开始使用C指针,并且您知道如何调试不可避免的错误
在封面下,有一个C结构表示tuple\u迭代器
。我认为它要么是一个结构,要么是一个形状完全相同的结构,但您应该通读tupleobject源代码以确保
下面是C中该类型的外观:
typedef struct {
PyObject_HEAD
Py_ssize_t it_index;
PyObject *it_seq; /* Set to NULL when iterator is exhausted */
} seqiterobject;
那么,如果创建一个与此大小相同的ctypes.Structure
子类,会发生什么情况,类似这样的情况:
class seqiterobject(ctypes.Structure):
_fields_ = (
('ob_refcnt', ctypes.c_ssize_t),
('ob_type', ctypes.c_void_p),
('it_index', ctypes.c_ssize_t),
('it_seq', ctypes.POINTER(ctypes.pyobject)))
…然后这样做:
seqiter = seqiterobject.from_address(id(j))
seqiter.it_seq = id(other_tuple)
…然后这样做:
seqiter = seqiterobject.from_address(id(j))
seqiter.it_seq = id(other_tuple)
…?好的,您可能会由于引用不足而损坏堆(并且还会泄漏旧值),因此您需要先增加新值,然后减少旧值
但是,如果您这样做……很可能,它会在下次调用\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
如果需要更多执行类似操作的示例代码,请参阅。除了sekiterobject
甚至不是一个公共类型,因此它更具黑客性之外,其他一切基本上都是一样的。您可以编写自己的协同程序
,并将新的tup发送给它
def coro(iterable):
iterable = iter(iterable)
while True:
try:
v = next(iterable)
i = yield v
except StopIteration:
break
if i:
yield v
iterable = it.chain(iterable, i)
那么这就如你所描述的那样起作用了:
In []:
blah = True
tup = ({'abc': 'a'}, {'2': '2'})
to_add = {'goof': 'abcde'}
c = coro(tup)
for i in c:
if blah:
i = c.send((to_add,))
blah = False
print(i)
Out[]:
{'abc': 'a'}
{'2': '2'}
{'goof': 'abcde'}
我确信在上面的文章中我遗漏了很多边缘情况,但它应该能让您了解如何做到这一点。您不能像更改原始元组一样更改元组迭代器中的元组。因为它们是同一个元组。正如我在前面的问题中所解释的,为什么不在while循环中根据元组的长度进行循环呢?类似于当我
时,我意识到我无法更改tuple。我不想改变元组。我试图将tuple_迭代器指向新的tuple。“如何修改这个tuple_生成器,使其指向新的tup,而不是旧的tup?这可能吗?”不,不可能。tuple\u iterator
上没有API来更改它所引用的元组,甚至没有私有的和未记录的元组。编写您自己的协同程序,然后发送要添加到其中的新元组。