Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python,比较一个数字列表并不断循环,直到出现';没有重复的_Python_List_Loops - Fatal编程技术网

Python,比较一个数字列表并不断循环,直到出现';没有重复的

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循环,

我正在尝试创建一个简单的脚本,它将帮助我进行网络规划

我有一张号码表--

对于每一个重复的数字,我希望用一个负1的新数字替换2个重复的数字。例如,用20替换21中的(2)。将(2)23s更换为22,依此类推

我有--

这样我就能得到我想要的--

但在我的最终输出中有(2)个20秒,需要用19替换,然后剩下的(2)个19秒需要用18替换

我如何在这里不断循环我的逻辑

我的最终输出应该是[18,21,22]

下面的代码让我得到了我想要的,但它很糟糕,我不知道在我的子网列表更改时要使用多少for循环,如果我在子网列表中有额外的10个数字,我不想每次都更改脚本来继续创建这些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]