我根据屏幕上对象的位置处理对象的鼠标点击。我记录了鼠标单击的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)
第一种方法似乎很慢,因为我必须将所有(可能很多)列表和单个对象复制到一个列表中。
第二种方法似乎很理想,因为它结构紧凑,易于维护。虽然,现在它只是伪代码。
第三种方法是笨重而笨重。
我应该使用哪种方法?如果第二个,你能给出实际的代码吗?
答案 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树或四叉树之类的东西)索引并快速查找。