遍历列表时更改列表的最佳方法 [英] Best method for changing a list while iterating over it

查看:103
本文介绍了遍历列表时更改列表的最佳方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在python脚本(v2.6)中有多个实例,需要在其中修改列表.我需要从列表中弹出值以响应用户的交互输入,并想知道执行此操作最干净的方法.目前,我有一个非常肮脏的解决方案:a)将要删除的列表项设置为False,然后使用过滤器或列表理解项将其删除;或者b)在循环中生成一个全新的列表,这似乎是不必要的将变量添加到名称空间并占用内存.

I have several instances in a python script (v2.6) where I need to modify a list in-place. I need to pop values from the list in response to interactive input from the user and would like to know the cleanest method of doing this. Currently I have the very dirty solutions of a) setting items in the list that I want to remove to False and removing them with a filter or list comprehension or b) generating an entirely new list while going through the loop, which seems to be needlessly adding variables to the namespace and taking up memory.

此问题的示例如下:

for i, folder in enumerate(to_run_folders):
    if get_size(folder) < byte_threshold:
        ans = raw_input(('The folder {0}/ is less than {1}MB.' + \
                    ' Would you like to exclude it from' + \
                    ' compression? ').format(folder, megabyte_threshold))
        if 'y' in ans.strip().lower():
            to_run_folders.pop(i)

我想查看列表中的每个文件夹.如果当前文件夹小于特定大小,我想问用户是否要排除它.如果是这样,请从列表中弹出文件夹.

I would like to look at each folder in the list. If the current folder is less than a certain size, I want to ask the user if they want to exclude it. If they do, pop the folder from the list.

此例程的问题是,如果我遍历列表,则会得到意外的行为并提前终止.如果我通过切片来遍历一个副本,则pop不会提取正确的值,因为索引会移动,并且随着弹出更多项目,问题会更加复杂.我也需要在脚本的其他区域进行这种动态列表调整.这种功能是否有任何干净的方法?

The problem with this routine is that if I iterate over the list, I get unexpected behavior and early termination. If I iterate over a copy by slicing, pop doesn't pull the right value because the indices are shifted and the problem compounds as more items are popped. I have a need for dynamic list adjustment of this kind in other areas of my script as well. Is there any clean method for this kind of functionality?

推荐答案

您可以向后循环列表,也可以使用视图对象.

You can loop over the list backwards, or use a view object.

有关如何向后循环遍历列表,请参见 https://stackoverflow.com/a/181062/711085 .基本上使用reversed(yourList)(会创建一个向后访问的视图对象).

See https://stackoverflow.com/a/181062/711085 for how to loop over a list backwards. Basically use reversed(yourList) (which happens creates a view object which visits backwards).

如果您需要索引,则可以执行reversed(enumerate(yourList)),但这将有效地在内存中创建一个临时列表,因为enumerate将需要在reversed插入之前运行.您将需要执行索引操作,或执行以下操作:

If you require indexing, you could do reversed(enumerate(yourList)), but that would effectively create a temporary list in memory because enumerate would need to run before reversed could kick in. You will need to either do index manipulation, or to do this:

for i in xrange(len(yourList)-1, -1, -1):
    item = yourList[i]
    ...

即使是更清洁的人:reversed也知道range,因此您可以在python3或python2(如果使用xrange代替)中做到这一点:

Even cleaner: reversed is aware of range, so you can do this in python3, or in python2 if you use xrange instead:

for i in reversed(range(len(yourList))):  
    item = yourList[i]
    ...

(证明:您可以执行next(reversed(range(10**10))),但是如果使用python2,这会使您的计算机崩溃)

(proof: you can do next(reversed(range(10**10))), but this will crash your computer if using python2)

这篇关于遍历列表时更改列表的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆