python for循环列表加一个项目

时间:2011-12-02 08:35:56

标签: python list

我根据屏幕上对象的位置处理对象的鼠标点击。我记录了鼠标单击的xy坐标,看它是否与允许点击的任何对象相匹配。对象在不同的​​列表中或只是单个对象,但是我希望它们在一个大的列表中,所以我可以循环遍历整个事物,如果点击其中一个对象,则执行工作,中断。您只能单击一个对象。

第一种方法:我现在是怎么做的:

list = [obj1, obj2, obj3]
singleobj

copylist = list
copylist.append(singleobj)

for item in copylist:
    if item.pos == mouseclick.pos:
        doWork(item)
        break

第二种方法:我宁愿做类似下面的事情,但显然list+singleobj无效:

for item in list+singleobj:
    if item.pos == mouseclick.pos:
        doWork(item)
        break

第三种方法:或者如果我必须这样做,我可以做这个可怕的糟糕代码:

list = [obj1, obj2, obj3]

foundobj = None

for item in list:
    if item.pos == mouseclick.pos:
        foundobj = item
        break

if foundobj is None:
    if singleobj.pos == mouseclick.pos:
        foundobj = singleobj

#possibly repeated several times here....


if foundobj is not None:
    doWork(foundobj)

第一种方法似乎很慢,因为我必须将所有(可能很多)列表和单个对象复制到一个列表中。

第二种方法似乎很理想,因为它结构紧凑,易于维护。虽然,现在它只是伪代码。

第三种方法是笨重而笨重。

我应该使用哪种方法?如果第二个,你能给出实际的代码吗?

2 个答案:

答案 0 :(得分:10)

对于第二种方法,您需要itertools.chain

for item in itertools.chain(list, [singleobj]):
    ...

答案 1 :(得分:3)

DrTyrsa的答案就是我对你的确切问题所说的话,但是让我给你一些其他提示:

copylist = list
copylist.append(singleobj)

这不会创建列表的副本,您可能希望copylist = list[:]copylist = list(lst)(我将此处的名称更改为lst,因为list是一个内置。你知道。)

关于你的第二种方法,你可以这样做:

for item in list + [singleobj]:
    ...

如果你打算使用itertools,一个微小的改进是使用一个元组而不是一个列表来保存额外的对象,因为它更轻一点:

for item in itertools.chain(list, (singleobj,)):
    ...

另一件事是你不应该循环你的对象以查看坐标是否匹配,你可以让它们通过它们的边界(像BSP树或四叉树之类的东西)索引并快速查找。