Python for a list of loops plus one element

I handle mouse clicks on objects depending on the location of the object on the screen. I record the xy coordinate of the mouse click and see if it matches any of the objects that are allowed to click on. The objects are in different lists or only in single objects, but I want them to be in one big list, so I can just skip this whole thing once, if the click is on one of the objects, do the work, take a break. You can click only one object.

First method: how am I doing it now:

list = [obj1, obj2, obj3] singleobj copylist = list copylist.append(singleobj) for item in copylist: if item.pos == mouseclick.pos: doWork(item) break 

Second method: I would prefer to do something like below, but obviously list+singleobj not valid:

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

Third method: or, if I absolutely need it, I could make this terrible horrible code:

 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) 

The first method seems slow because I need to copy all (possibly many) lists and individual objects into one list.

The second method seems ideal, because it is compact and easy to maintain. Although, as of now, this is just pseudo-code.

The third method is cumbersome and awkward.

Which method to use? If the second, can you provide the actual code?

+4
source share
2 answers

For the second method you need itertools.chain

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

DrTyrsa's answer is what I wanted to say about your exact question, but let me give you some other tips:

 copylist = list copylist.append(singleobj) 

this does not create a copy of the list, you may want to make copylist = list[:] or copylist = list(lst) (I changed the name here to lst because list is inline, you know).

about your second method, you can do:

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

and if you are going to use itertools, a tiny improvement is to use a tuple rather than a list to store an additional object, as it is a bit lighter:

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

Another thing is that you do not have to loop your objects to see if the coordinates match, you can index them along their borders (in something like a BSP or Quadtree tree) and do a quick search.

+3
source

Source: https://habr.com/ru/post/1384273/


All Articles