python for循环列表加一个项目

jb.*_*jb. 4 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
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)


for*_*ran 5

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 树或四叉树中)并进行更快的查找。