Path: csiph.com!usenet.pasdenom.info!dedibox.gegeweb.org!gegeweb.eu!nntpfeed.proxad.net!proxad.net!feeder1-2.proxad.net!usenet-fr.net!nerim.net!novso.com!newsfeed.xs4all.nl!newsfeed1a.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.019 X-Spam-Evidence: '*H*': 0.96; '*S*': 0.00; 'else:': 0.03; '21,': 0.07; 'attribute': 0.07; 'welcome.': 0.07; 'python': 0.11; 'def': 0.12; 'jan': 0.12; '(there': 0.16; 'algorithm.': 0.16; 'be:': 0.16; 'before.': 0.16; 'dict': 0.16; 'nodes': 0.16; 'objects.': 0.16; 'responded.': 0.16; 'sill': 0.16; 'subject:which': 0.16; ':-)': 0.16; 'wrote:': 0.18; 'code.': 0.18; 'do.': 0.18; 'solution.': 0.20; 'example': 0.22; 'print': 0.22; 'header:User-Agent:1': 0.23; 'example.': 0.24; 'this:': 0.26; 'pass': 0.26; 'header:In-Reply- To:1': 0.27; 'function': 0.29; 'raise': 0.29; 'list:': 0.30; 'robert': 0.30; 'code': 0.31; 'libraries': 0.31; 'node': 0.31; 'object.': 0.31; 'pos': 0.31; 'class': 0.32; 'skip:_ 10': 0.34; 'maybe': 0.34; 'skip:d 20': 0.34; 'could': 0.34; 'info': 0.35; 'objects': 0.35; 'but': 0.35; 'received:google.com': 0.35; 'there': 0.35; 'false': 0.36; 'processed': 0.36; 'subject:data': 0.36; 'done': 0.36; "didn't": 0.36; 'thanks': 0.36; 'subject:?': 0.36; 'should': 0.36; 'changing': 0.37; 'list': 0.37; 'list.': 0.37; 'clear': 0.37; 'implement': 0.38; 'message-id:@gmail.com': 0.38; 'lists.': 0.38; 'to:addr:python-list': 0.38; 'skip:- 10': 0.38; 'explain': 0.39; 'structure': 0.39; 'to:addr:python.org': 0.39; 'remove': 0.60; 'skip:o 30': 0.61; 'new': 0.61; 'first': 0.61; 'content-disposition:inline': 0.62; 'skip:n 10': 0.64; 'pick': 0.64; 'provide': 0.64; 'more': 0.64; 'different': 0.65; 'chance': 0.65; 'here': 0.66; 'between': 0.67; 'lowest': 0.74; 'myself)': 0.84; 'oscar': 0.84; 'partially': 0.84; 'mean.': 0.91 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:from:to:subject:message-id:references:mime-version :content-type:content-disposition:content-transfer-encoding :in-reply-to:user-agent; bh=DWrydtSVbFTmXmIq/PN2bHO4yrB92olsFqJFy+KktyE=; b=SYMY6DL2xFPQZW6ITVYUtHBsacYN11+BEPTmbZGM4MiOWml1cn8n1tZ3VBfP4oGS+D kMbrHfJpPXX7H/7bsD6EEBt1ebWSCAwchOVBku45hwRgr7BfbDnyzJDPc6hGUZHMYcPi Au62YvrEen891giP4YFdo3JsHHw09V0PCuncTGyTZ/MIQR4pi7oTJfPuvb7qhoa8FoeQ EdERRZ8DQW+XNBqi8Hs0+WGikUfF/0v/JIvYwSkXw4QiNpjFO/a2J4pRKkuR4jckx4kC r8BX5oYeVy6pzNhdBFyD2NTJ/CHN5rfPtrksamgL/abII9GEmSZKvESlhgR1/GqMj9So UcWw== X-Received: by 10.180.20.15 with SMTP id j15mr14818915wie.4.1390312749705; Tue, 21 Jan 2014 05:59:09 -0800 (PST) Date: Tue, 21 Jan 2014 13:59:06 +0000 From: Oscar Benjamin To: python-list@python.org Subject: Re: which data structure to use? References: MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 157 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1390312751 news.xs4all.nl 2846 [2001:888:2000:d::a6]:59973 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:64412 On Tue, Jan 21, 2014 at 05:38:34AM -0800, Robert Voigtländer wrote: > > > On Tue, Jan 21, 2014 at 03:17:43AM -0800, Robert Voigtl�nder wrote: > > > > > > I have objects like this: > > > > > > > > > > class Node(object): > > > > > def __init__(self, pos, parent, g , h): > > > > > self.pos = pos > > > > > self.parent = parent > > > > > self.g = g > > > > > self.h = h > > > > > self.f = g+h > > > > > > > > > > > > > > > I need to build a "list" of these objects. The amount is unknown. > > > > > On this list I need to regularly > > > > > > > > > > 1. check if a specific item - identified by Node.pos - is in the list. > > > > > 2. find the object with the lowest Node.f attribute and update or remove it > > > > > First thanks to all who responded. Although I only partially understand your answers as I am a Python starter. > What's clear to me is the difference between object and instance of an object. Just didn't explain it well. > > Maybe I give some more info on what I need / want to do. I will also provide a working code example. Should have done this before. > > I would very much appreciate a working example of what you mean. Then I have a chance to understand it. :-) > > I would like to implement a class for a A* pathfinding algorithm. (there are ready libraries out there but I would like to learn it myself) This requires to maintain a list of nodes to be processed and nodes already processed. For new nodes I need to check if they are on one of the lists. I also need to regularly pick the node with the lowest value f from the list. > > Here some working code. For one function I sill need a solution. Any better solution is welcome. > > Thanks > Robert > > --------------- > class Node: > def __init__(self, pos, parent, g , h): > self.pos = pos > self.parent = parent > self.g = g > self.h = h > self.f = g+h > > > def isinlist(nodeToSeatch): > for item in openlist: > if item.pos == nodeToSeatch: return True > return False > > > def lowestF(): > lowestF = '' > for item in openlist: > if item.f < lowestF: lowestF = item > return lowestF The function above is incorrect. I think it should be: def lowestF(): lowestF = '' for item in openlist: if item.f < lowestF: lowestF = item.f # Note the .f here return lowestF > > def deleteItemWithPos(pos): > ## need this function or different approach > pass def deleteItemWithPos(pos): for n, item in enumerate(openlist): if item.pos == pos: del openlist[n] return else: raise RuntimeError('Not in the list!') > > openlist=[] > openlist.append(Node((1,1),None,1,5)) > openlist.append(Node((1,2),(1,1),4,6)) > openlist.append(Node((1,3),(1,2),9,10)) > > for item in openlist: print item.pos, item.f > > print isinlist((1,1)) > print isinlist((1,5)) > > nextNode = lowestF() > print nextNode.pos, nextNode.f My first suggestion would be to use a dict instead of a list: class Node: def __init__(self, pos, parent, g , h): self.pos = pos self.parent = parent self.g = g self.h = h self.f = g+h def isinlist(pos): return pos in opendict def lowestF(): return min(opendict.values(), key=lambda x: x.f) def deleteItemWithPos(pos): del opendict[pos] nodes = [ Node((1,1),None,1,5), Node((1,2),(1,1),4,6), Node((1,3),(1,2),9,10), ] opendict = {} for node in nodes: opendict[node.pos] = node for item in opendict.values(): print item.pos, item.f print isinlist((1,1)) print isinlist((1,5)) nextNode = lowestF() print nextNode.pos, nextNode.f The above is more efficient and simpler. It is still O(N) for the lowestF() function. Changing data structure could make that more efficient. Oscar