Python,比较一个数字列表并不断循环,直到出现';没有重复的
我正在尝试创建一个简单的脚本,它将帮助我进行网络规划 我有一张号码表-- 对于每一个重复的数字,我希望用一个负1的新数字替换2个重复的数字。例如,用20替换21中的(2)。将(2)23s更换为22,依此类推 我有-- 这样我就能得到我想要的-- 但在我的最终输出中有(2)个20秒,需要用19替换,然后剩下的(2)个19秒需要用18替换 我如何在这里不断循环我的逻辑 我的最终输出应该是[18,21,22] 下面的代码让我得到了我想要的,但它很糟糕,我不知道在我的子网列表更改时要使用多少for循环,如果我在子网列表中有额外的10个数字,我不想每次都更改脚本来继续创建这些for循环Python,比较一个数字列表并不断循环,直到出现';没有重复的,python,list,loops,Python,List,Loops,我正在尝试创建一个简单的脚本,它将帮助我进行网络规划 我有一张号码表-- 对于每一个重复的数字,我希望用一个负1的新数字替换2个重复的数字。例如,用20替换21中的(2)。将(2)23s更换为22,依此类推 我有-- 这样我就能得到我想要的-- 但在我的最终输出中有(2)个20秒,需要用19替换,然后剩下的(2)个19秒需要用18替换 我如何在这里不断循环我的逻辑 我的最终输出应该是[18,21,22] 下面的代码让我得到了我想要的,但它很糟糕,我不知道在我的子网列表更改时要使用多少for循环,
subnets = [21, 21, 21, 19, 20, 23, 23]
x = sorted(subnets)
z = []
y = []
v = []
for a in x:
if a not in z:
z.append(a)
else:
z.remove(a)
z.append(a-1)
for a in z:
if a not in y:
y.append(a)
else:
y.remove(a)
y.append(a-1)
for a in y:
if a not in v:
v.append(a)
else:
v.remove(a)
v.append(a-1)
print(v)
以下解决方案在性能方面可能不太理想,但似乎很容易理解。您需要一个标准Python库中的
计数器
对象来统计列表中的重复对象
subnets = [21, 21, 21, 19, 20, 23, 23]
from collections import Counter
只要存在重复项,循环就会继续,也就是说,项目集的长度小于项目列表的长度(项目集消除重复项)
以下解决方案在性能方面可能不太理想,但似乎很容易理解。您需要一个标准Python库中的
计数器
对象来统计列表中的重复对象
subnets = [21, 21, 21, 19, 20, 23, 23]
from collections import Counter
只要存在重复项,循环就会继续,也就是说,项目集的长度小于项目列表的长度(项目集消除重复项)
这与您的想法类似,我们只是在while循环中运行替换操作,修改一个适当的列表:
def replace_pairs_minus_one(inp):
l = inp[:]
while(True):
for i, e in enumerate(l):
if e in l[i+1:]:
# pair found
# here we modify the list, since we are breaking anyway
l[i] = e - 1
l.remove(e)
break
else:
# break out of while if no pairs found
break
return sorted(l)
subnets = [21, 21, 21, 19, 20, 23, 23]
pairs_removed = replace_pairs_minus_one(subnets) # [18, 21, 22]
这与您的想法类似,我们只是在while循环中运行替换操作,修改一个适当的列表:
def replace_pairs_minus_one(inp):
l = inp[:]
while(True):
for i, e in enumerate(l):
if e in l[i+1:]:
# pair found
# here we modify the list, since we are breaking anyway
l[i] = e - 1
l.remove(e)
break
else:
# break out of while if no pairs found
break
return sorted(l)
subnets = [21, 21, 21, 19, 20, 23, 23]
pairs_removed = replace_pairs_minus_one(subnets) # [18, 21, 22]
你的问题似乎需要更多的细节,你说的两个副本是什么意思???是否只删除重复次数为2次的元素?只要有重复次数,请删除该数字,并将其替换为比原始重复次数少1的新数字。只需在具有有用条件的while循环中运行循环(如未找到重复项)。您不应该修改正在迭代的列表。是要替换/删除所有重复项,还是仅替换/删除对?对于三个相等的数字,你想怎么做?DYZ提出了一个很好的解决方案——任何一对数字都需要替换为比这对数字低1的新数字。20和20将被一个19取代。20,20,20需要等于19,20。你的问题似乎需要更多的细节,2个重复是什么意思???是否只删除重复次数为2次的元素?只要有重复次数,请删除该数字,并将其替换为比原始重复次数少1的新数字。只需在具有有用条件的while循环中运行循环(如未找到重复项)。您不应该修改正在迭代的列表。是要替换/删除所有重复项,还是仅替换/删除对?对于三个相等的数字,你想怎么做?DYZ提出了一个很好的解决方案——任何一对数字都需要替换为比这对数字低1的新数字。20和20将被一个19取代。20,20,20需要等于19,20。虽然这无疑是聪明的,但至少对于这里给出的简短输入来说,这要比(正如您已经估计的)慢4倍。@JanChristophTerasa这是我在第一句话中说的。@JanChristophTerasa同样,对于较长的列表(700个数字),我的解决方案比您的快100倍。大概是因为
remove
是一个非常慢的操作。听起来很合理remove
是O(n),我也在运行循环数次,所以我的解决方案可能会像O(n^2)那样扩展。您的解决方案可以更好地扩展,因此它不是次优的。可能有更快的算法,但这是非常好的。虽然这无疑是聪明的,但至少对于这里给出的简短输入来说,这比(正如您已经估计的)慢了大约4倍。@JanChristophTerasa这是我在第一句话中说的。@JanChristophTerasa同样,对于更长的列表(700个数字),我的解决方案比你的快100倍。大概是因为remove
是一个非常慢的操作。听起来很合理remove
是O(n),我也在运行循环数次,所以我的解决方案可能会像O(n^2)那样扩展。您的解决方案可以更好地扩展,因此它不是次优的。可能有更快的算法,但这是相当好的。
while len(subnets) > len(set(subnets)):
# [v-1] * (cnt // 2) - even # of duplicates
# [v] * (cnt % 2) - odd remaining non-duplicate
# sum() rebuilds the list from the sublists
subnets = sum([[v-1] * (cnt // 2) + [v] * (cnt % 2)
for v, cnt in Counter(subnets).items()], [])
# [18, 21, 22]
def replace_pairs_minus_one(inp):
l = inp[:]
while(True):
for i, e in enumerate(l):
if e in l[i+1:]:
# pair found
# here we modify the list, since we are breaking anyway
l[i] = e - 1
l.remove(e)
break
else:
# break out of while if no pairs found
break
return sorted(l)
subnets = [21, 21, 21, 19, 20, 23, 23]
pairs_removed = replace_pairs_minus_one(subnets) # [18, 21, 22]