tag:blogger.com,1999:blog-684183198890094283.post7696441794024773171..comments2023-11-05T06:12:59.718-05:00Comments on S.Lott-Software Architect: Amazing SpeedupS.Lotthttp://www.blogger.com/profile/06337323642834330176noreply@blogger.comBlogger7125tag:blogger.com,1999:blog-684183198890094283.post-26249711742285755612010-12-29T18:41:11.579-05:002010-12-29T18:41:11.579-05:00Oh, I see. The data is the index and value from a ...Oh, I see. The data is the index and value from a column, and the code is to fill in the "missing" numbers with Nones?<br /><br />A defaultdict may be perfect for this. Since source is already in the form of a series of a list of (index, value) tuples, we can just pass this straight to the constructor.<br /><br />>>> source = [ (1, 'a'), (5, 'b') ]<br />>>> import collections<br />>>> data = collections.defaultdict(lambda: None, source)<br /><br />(add a list comprehension to call SomeClass constructor: collections.defaultdict(lambda: None, [(k, SomeClass(v)) for k,v in source])<br /><br />Then your code can just treat data as if it were a list for indexing.<br /><br />>>> data[1]<br />'a'<br />>>> data[2]<br />>>> data[3]<br />>>> data[4]<br />>>> data[5]<br />'b'<br /><br />If you want to make it into a real list (for slicing, etc) you can do this with a simple comprehension:<br /><br />>>> datalist = [data[a] for a in xrange(max(data.keys())+1)]<br />>>> datalist<br />[None, 'a', None, None, None, 'b']<br /><br />You could also replace this with a generator expression if you wanted to save memory I guess, but you may as well leave it as a defaultdict in that case.Kurt Rosehttps://www.blogger.com/profile/11161604109056835253noreply@blogger.comtag:blogger.com,1999:blog-684183198890094283.post-46933315272081877022010-12-29T18:38:02.457-05:002010-12-29T18:38:02.457-05:00This comment has been removed by the author.Kurt Rosehttps://www.blogger.com/profile/11161604109056835253noreply@blogger.comtag:blogger.com,1999:blog-684183198890094283.post-34460370546578136522010-12-29T18:34:08.611-05:002010-12-29T18:34:08.611-05:00This comment has been removed by the author.Kurt Rosehttps://www.blogger.com/profile/11161604109056835253noreply@blogger.comtag:blogger.com,1999:blog-684183198890094283.post-23515635645755947372010-12-29T18:27:39.458-05:002010-12-29T18:27:39.458-05:00This comment has been removed by the author.Kurt Rosehttps://www.blogger.com/profile/11161604109056835253noreply@blogger.comtag:blogger.com,1999:blog-684183198890094283.post-64319252270614190372010-12-29T17:29:38.903-05:002010-12-29T17:29:38.903-05:00The index is 1-based. It's the column number ...The index is 1-based. It's the column number from reading Excel spreadsheets.S.Lotthttps://www.blogger.com/profile/06337323642834330176noreply@blogger.comtag:blogger.com,1999:blog-684183198890094283.post-29049859852247495902010-12-29T16:36:17.569-05:002010-12-29T16:36:17.569-05:00I take it index from some_source must be increasin...I take it index from some_source must be increasing and start at least with 1? (The latter because starting at zero, which seems more natural for a general index, results in an infinite loop: counter + 1 will never equal 0. Was this an error in simplifying for the blog?)<br /><br />@Kurt: You can't eliminate counter as in either of those, as the number of Nones depends on the difference between successive indexes, not on index alone. Your code gives a different result.<br /><br />And realizing the importance is the difference between successive indexes leads me to write (how to format code for blogspot?):<br /><br />def something_iter():<br />..cur_index = 1 # instead of 0 for reason above<br />..for next_index, value in some_source:<br />....for _ in xrange(cur_index, next_index):<br />......yield None<br />....cur_index = next_index<br />....yield SomeClass(value)<br /><br />I don't consider this any significant improvement over the while loop version, but I think it would help prevent misunderstandings similar to Kurt's.Fredhttps://www.blogger.com/profile/15294157775492570492noreply@blogger.comtag:blogger.com,1999:blog-684183198890094283.post-2649965729259103942010-12-29T13:10:57.074-05:002010-12-29T13:10:57.074-05:00Interesting. You may consider just using a list c...Interesting. You may consider just using a list comprehension or generator expression as well for that second piece:<br /><br />[ [None]*index + [SomeClass(value)] for index,value in source ]<br /><br />itertools.chain.from_iterable( ( itertools.chain( itertools.repeat(None, index), [SomeClass(value)] ) for index, value in source ) )<br /><br />This arguably simplifies the code by removing the explicit "counter" variable, and the nested loop.Kurt Rosehttps://www.blogger.com/profile/11161604109056835253noreply@blogger.com