我正在尝试设置一个函数或类来存储具有添加,删除或检查存在的能力的唯一整数。这当然可以使用普通套装轻松实现。这里棘手的部分是显示范围。我的意思是,如果我有100到20000之间的所有数字,我不想显示中间所有数字的巨大列表,而是显示100-20000。
考虑以下示例:
numbers 3000,3008-3015,3020,3022,3030-3043,3068
目标是创建一个函数或类来添加,检查或检索有关当前数字的信息。以下是我的想象:
>>> f_check(3016)
False
>>> f_check(3039)
True
>>> f_add(3016)
3000,3008-3016,3020,3022,3030-3043,3068
>>> f_remove(3039)
3000,3008-3016,3020,3022,3030-3038,3040-3043,3068
>>> f_add(3100)
3000,3008-3016,3020,3022,3030-3038,3040-3043,3068,3100
依此类推......
同样,请注意范围部分(3030-3038,3040-3043)等。我不想显示连续数字的每个条目,而是显示“摘要”或范围。
再次使用相同的例子,如果我添加3021,我会期望以下结果:
>>> f_add(3021)
3000,3008-3016,3020-3022,3030-3043,3068
非常感谢您的想法!
答案 0 :(得分:1)
正如评论中的人所说,你的大部分操作都是简单的列表操作。但是,如果您的数据包含范围(例如3008-3015),那么它就变成了另一个故事。原因是你需要对该范围的含义进行某种解码。 我只使用函数(没有类)编写了一个简单的代码。
matched = False
检查数字或范围:
def valueCheck(val):
if "-" in val:
return False
else:
return True
将范围编码为两个值(开始,结束)
def rangeCheck(val):
if valueCheck(val):
return val, val
else:
return val.split("-")
检查数字是否与列表内容匹配:
def f_check(new_number, numbers_list):
global matched
for i in numbers_list:
rangeCheck(i)
if int(rangeCheck(i)[0]) <= int(new_number) <= int(rangeCheck(i)[1]):
print "{} matches {}".format(new_number, i)
matched = True
break
if not matched:
print "{} doesn't exist in your list".format(new_number)
在列表中添加一个数字:
def f_add(new_number, numbers_list):
numbers_list.append(new_number)
print numbers_list
从列表中删除一个数字:
def f_delete(new_number, numbers_list):
numbers_list.remove(new_number)
print numbers_list
假设您的数字是列表中的字符串值,如下所示:
numbers = ["3000", "3008-3015", "3020", "3022", "3030-3043", "3068"]
不匹配:
f_check("2000", numbers)
2000 doesn't exist in your list
单场比赛:
f_check("3020", numbers)
3020 matches 3020
范围匹配:
f_check("3010", numbers)
3010 matches 3008-3015
其他简单操作: 添加:
f_add("2000", numbers)
['3000', '3008-3015', '3020', '3022', '3030-3043', '3068', '2000']
删除:
f_delete("3068", numbers)
['3000', '3008-3015', '3020', '3022', '3030-3043']
请注意,使用以下内容可以更轻松地完成单个匹配:
number = "3020"
if number in numbers:
print "{} matched".format(number)
3020 matched
更新#1
克服你提出的问题&#34;如果需要,可以将数字添加到现有范围和/或创建新范围。我在How to group list of continuous values in ranges找到了类似的问题,可以解决部分问题。但是,在这种情况下,您的原始编码(val-val)不会有用。 要解决此问题,您可以执行以下操作:
第1步,请注释以下两行:
# rangeCheck(i)
# if int(rangeCheck(i)[0]) <= int(new_number) <= int(rangeCheck(i)[1]):
"""
you will not be using the rangeCheck() or valueCheck() anymore.
"""
第2步,添加此行而不是原始的IF语句:
if int(i[0]) <= int(new_number) <= int(i[1]):
第3步,添加此功能可以压缩您的数字列表
def flatList(numbers_list):
for i in numbers_list:
if len(str(i).split("-")) > 1:
numbers_list.extend(range(int(i.split("-")[0]), int(i.split("-")[1]) + 1))
numbers_list.remove(i)
return numbers_list
第4步,添加此功能(取自1),将您的单位列表分组为值范围
from operator import itemgetter
from itertools import groupby
def numbers_group(flatt_list):
flatt_list = [int(i) for i in flatt_list]
ranges = []
for k, g in groupby(enumerate(flatt_list), lambda (i, x): i - x):
group = map(itemgetter(1), g)
ranges.append((group[0], group[-1]))
return ranges
<强>用法:强>
numbers = ["3000", "3008-3015", "3020", "3022", "3030-3043", "3068"]
print flatList(numbers)
['3000', '3020', '3022', '3068', 3008, 3009, 3010, 3011, 3012, 3013, 3014, 3015, 3030, 3031, 3032, 3033, 3034, 3035, 3036, 3037, 3038, 3039, 3040, 3041, 3042, 3043]
print numbers_group(sorted(flatList(numbers)))
[(3008, 3015), (3030, 3043), (3000, 3000), (3020, 3020), (3022, 3022), (3068, 3068)]
numbers = f_add("3021", numbers)
print numbers_group(sorted(flatList(numbers)))
[(3008, 3015), (3030, 3043), (3000, 3000), (3020, 3022), (3068, 3068)]
numbers = f_delete("3021", numbers)
print numbers_group(sorted(flatList(numbers)))
[(3008, 3015), (3030, 3043), (3000, 3000), (3020, 3020), (3022, 3022), (3068, 3068)]
答案 1 :(得分:0)
由于您未指定格式化的含义,我假设您的意思是根据数字的升序排序数字列表。此外,我修改了您的列表并删除了某些数字之间的破折号。
话虽如此,我相信你要求的是sorted()
功能。直接来自文档:
Python列表有一个内置的list.sort()方法,可以就地修改列表。还有一个sorted()内置函数,它从可迭代构建一个新的排序列表。
我只是创建一个类,然后添加上面列出的方法。这堂课很简单。这是我要做的一个例子:
class IntList:
def __init__(self, *args):
self.lst = [int(i) for i in args]
self.lst.sort()
def add(self, arg):
self.lst.append(arg)
self.lst.sort()
def remove(self, arg):
self.lst.remove(arg)
self.lst.sort()
def check(self, arg):
return arg in self.lst
以下是一个示例用法:
>>> lst = IntList(1, 2, 3, 4, 5)
>>> lst.add(6)
>>> lst.lst
[1, 2, 3, 4, 5, 6]
>>> lst.remove(2)
>>> lst.lst
[1, 3, 4, 5, 6]
>>> lst.check(4)
True
>>> lst.check(90)
False
如果我的假设有误,请说明您的确切含义。
答案 2 :(得分:0)
好的,首先 - 感谢大家的努力。非常感谢。
这是我最终解决的问题。我只是用了一个类扩展了一个集合。修改它的输出。
class vlans(set):
def check(self,number):
if number in self:
return True
def __str__(self):
last = 0
out = []
for x in list(self):
if len(out)>0 and last+1==int(x):
out[-1] = out[-1].split("-")[0]+"-"+str(x)
else:
out.append(str(x))
last = int(x)
return ",".join(out)
以下是它的工作原理:
>>> f=vlans([3008, 3009, 3010, 3011, 3012, 3013, 3014,
3015, 3020, 3022, 3030, 3031, 3032, 3033, 3034, 3035,
3036, 3037, 3038, 3039, 3040, 3041, 3042, 3000, 3068])
>>>
>>>
>>> print f
3000,3008-3015,3020,3022,3030-3042,3068
>>> f.check(3021)
>>> f.add(3021)
>>> f.check(3021)
True
>>> print f
3000,3008-3015,3020-3022,3030-3042,3068
>>> f.remove(3035)
>>> print f
3000,3008-3015,3020-3022,3030-3034,3036-3042,3068
对我所需要的模糊描述道歉,但希望现在一切都有意义!