下面是我编写的一个函数,用于在书籍中显示页码。
例如,如果输入列表[1,2,3,6,7,10],它将返回:
1-3,6-7,10这似乎是一个很好的例子,说明如何在Python中使用字典数据类型。
是否有一种更有效的代码方法来做到这一点?
def formatpagelist (numberlist):
tempdic={}
returnstring=''
for number in numberlist:
if number-1 in tempdic.keys():
tempdic[number-1]=number
elif number-1 in tempdic.values():
for key in tempdic.keys():
if number-1==tempdic[key]: foundkey=key
tempdic[foundkey]=number
else:
tempdic[number]=0
keylist=list(tempdic.keys())
keylist.sort()
for key in keylist:
if tempdic[key]>0:
returnstring+=(str(key)+'-'+str(tempdic[key])+',')
else: returnstring+=str(key)+','
return returnstring发布于 2011-10-05 17:51:58
不使用字典的稍微短一些的版本:
def formatpagelist(numberlist):
prev_number = min(numberlist) if numberlist else None
pagelist = list()
for number in sorted(numberlist):
if number != prev_number+1:
pagelist.append([number])
elif len(pagelist[-1]) > 1:
pagelist[-1][-1] = number
else:
pagelist[-1].append(number)
prev_number = number
return ','.join(['-'.join(map(str,page)) for page in pagelist])发布于 2011-10-06 00:07:54
def formatpagelist (numberlist):python样式指南推荐函数名为words_with_underscores。
tempdic={}这是一个非常糟糕的变量名。它没有告诉我变量的用途。它告诉我变量是临时的(和所有变量一样),它是一个dict,这在{}中是显而易见的。
returnstring=''直到晚些时候才会出现..。为什么会在这里?
for number in numberlist:
if number-1 in tempdic.keys():这和number - 1 in tempdic:一样
tempdic[number-1]=number
elif number-1 in tempdic.values():
for key in tempdic.keys():
if number-1==tempdic[key]: foundkey=key如果你已经扫描了字典的键,这是一个你可能不应该使用字典的迹象。
tempdic[foundkey]=number
else:
tempdic[number]=0
keylist=list(tempdic.keys())
keylist.sort()这和keylist = sorted(tempdic)是一样的
for key in keylist:
if tempdic[key]>0:
returnstring+=(str(key)+'-'+str(tempdic[key])+',')
else: returnstring+=str(key)+','我认为把这些放在一条线上会让人更难读懂。通常情况下,最好先建立一个列表,然后加入列表。
return returnstring这是另一种方法:我从@Jeff那里偷了一些部件,但我想尝试另一种方法。
import collections
pages = [1,2,5,6,7,9]
starts = collections.OrderedDict()
ends = collections.OrderedDict()
for idx, page in enumerate(pages):
section = page - idx
starts.setdefault(section, page)
ends[section] = page
page_parts = []
for section, start in starts.items():
end = ends[section]
if start == end:
page_parts.append("{0}".format(start))
else:
page_parts.append("{0}-{1}".format(start, end))
print(','.join(page_parts))发布于 2011-10-06 19:01:44
你对字典的使用似乎是一种让数字不符合顺序的方法。与其对它们进行排序,不如使用字典(以及相关的散列)来最大限度地提高效率。
这并不是很完美,因为您最终会对给定的值进行顺序搜索。
散列低:高范围(字典键:值对)以避免搜索没有多大帮助。只有他们的钥匙会被散列。在低端扩展范围的情况下,它确实有帮助。但是,为了在高端扩展范围,您必须使用字典值的搜索。
您真正创建的是“分区”的集合。每个分区都有一个低值和高值的边界。而不是字典,你也可以使用一个微不足道的元组(低,高)。对于大多数Pythonic来说,(低,高)对包括低,但不包括高。这是“半开区间”。
这里有一个使用简单的元组set的版本,它依赖于散列而不是二分法。
二进制搜索(使用bisect模块)也可能执行得很好。这将稍微简化相邻范围的合并,因为这两个范围实际上是相邻的。然而,这会导致重组顺序的成本。
从一组空的分区开始,第一个数字就会创建一个简单的分区。
下一个数字可以引出三件事中的一件。
就像这样。
def make_ranges(numberlist):
ranges=set()
for number in numberlist:
print ranges, number
adjacent_to = set( r for r in ranges if r[0]-1 == number or r[1] == number )
if len(adjacent_to) == 0:
# Add a new partition.
r = (number,number+1)
assert r[0] <= number < r[1] # Trivial, right?
ranges.add( r )
elif len(adjacent_to) == 1:
# Extend this partition, build a new range.
ranges.difference_update( adjacent_to )
r= adjacent_to.pop()
if r[0]-1 == number: # Extend low end
r= (number,r[1])
else:
r= (r[0],number+1) # Extend high end
assert r[0] <= number < r[1]
ranges.add( r )
elif len(adjacent_to) == 2:
# Merge two adjacent partitions.
ranges.difference_update( adjacent_to )
r0= adjacent_to.pop()
r1= adjacent_to.pop()
r = ( min(r0[0],r1[0]), max(r0[1],r1[1]) )
assert r[0] <= number < r[1]
ranges.add( r )
return ranges这是对您的算法进行的非常彻底的重新思考,所以这不是一个正确的代码评审。
在Python中,用分隔符组装字符串更简单。对于","-separated字符串的例子,请始终考虑这样做。
final = ",".join( details )一旦你有了它,你只需要做一系列的细节。在这种情况下,每个细节都是"x“或”x“,作为范围可以采取的两种形式。
所以一定是这样的
details = [ format_a_range(r) for r in ranges ]在本例中,我将格式显示为内联def。它也可以作为一个if-else表达式来完成。
根据您的范围,总体功能是这样的。
def formatpagelist (numberlist):
ranges= make_ranges( numberlist )
def format_a_range( low, high ):
if low == high-1: return "{0}".format( low )
return "{0}-{1}".format( low, high-1 )
strings = [ format_a_range(r) for r in sorted(ranges) ]
return ",".join( strings )https://codereview.stackexchange.com/questions/5196
复制相似问题