我正在根据屏幕上对象的位置处理对象的鼠标点击.我记录了鼠标单击的xy坐标,看它是否与允许点击的任何对象相匹配.对象在不同的列表中或只是单个对象,但是我希望它们在一个大的列表中,所以我可以遍历整个事物一次,如果点击其中一个对象,那么就完成工作,中断.您只能单击一个对象.
第一种方法:我现在是怎么做的:
list = [obj1, obj2, obj3]
singleobj
copylist = list
copylist.append(singleobj)
for item in copylist:
if item.pos == mouseclick.pos:
doWork(item)
break
Run Code Online (Sandbox Code Playgroud)
第二种方法:我宁愿做下面的事情,但显然这list+singleobj是无效的:
for item in list+singleobj:
if item.pos == mouseclick.pos:
doWork(item)
break
Run Code Online (Sandbox Code Playgroud)
第三种方法:或者如果我绝对必须,我可以做这个可怕的可怕代码:
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)
Run Code Online (Sandbox Code Playgroud)
第一种方法似乎很慢,因为我必须将所有(可能很多)列表和单个对象复制到一个列表中.
第二种方法看起来很理想,因为它结构紧凑,易于维护.虽然,现在它只是伪代码.
第三种方法是笨重而笨重.
我应该使用哪种方法?如果是第二个,你能给出实际代码吗?
DrT*_*rsa 10
对于你需要的第二种方法 itertools.chain
for item in itertools.chain(list, [singleobj]):
...
Run Code Online (Sandbox Code Playgroud)
Tyrsa 博士的回答正是我要针对您的具体问题所说的,但让我给您一些其他提示:
copylist = list
copylist.append(singleobj)
Run Code Online (Sandbox Code Playgroud)
这不会创建列表的副本,您可能想要这样做copylist = list[:]或copylist = list(lst)(我将此处的名称更改为lst,因为list它是内置的。您知道)。
关于你的第二种方法,你可以这样做:
for item in list + [singleobj]:
...
Run Code Online (Sandbox Code Playgroud)
如果您打算使用 itertools,一个微小的改进是使用元组而不是列表来保存额外的对象,因为它更轻量级:
for item in itertools.chain(list, (singleobj,)):
...
Run Code Online (Sandbox Code Playgroud)
另一件事是你不应该循环你的对象来查看坐标是否匹配,你可以让它们按边界索引(在 BSP 树或四叉树中)并进行更快的查找。