Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/329.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.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 - Fatal编程技术网

Python 在列表中查找重复的数字并使其唯一

Python 在列表中查找重复的数字并使其唯一,python,Python,我正在尝试实现一个遗传算法,我的交叉函数需要这个。我需要弄清楚的是以下几点。 如果我有名单 [0, 1, 6, 7, 5, 4, 3, 2, 1] 它有重复的元素。我想以名单结束 [0, 8, 6, 7, 5, 4, 3, 2, 1] 我得到这个列表的原因是我从左到右查看每个元素。我在索引1中看到了数字“1”,它也存在于列表中。因此,我将其更改为不在列表中的元素。列表中最小的元素是0,最大的元素是len(list)-1 在这种情况下,列表的顺序很重要。因此,我不认为将其转换为集合是合适的。我

我正在尝试实现一个遗传算法,我的交叉函数需要这个。我需要弄清楚的是以下几点。 如果我有名单

[0, 1, 6, 7, 5, 4, 3, 2, 1]
它有重复的元素。我想以名单结束

[0, 8, 6, 7, 5, 4, 3, 2, 1]
我得到这个列表的原因是我从左到右查看每个元素。我在索引1中看到了数字“1”,它也存在于列表中。因此,我将其更改为不在列表中的元素。列表中最小的元素是0,最大的元素是len(list)-1

在这种情况下,列表的顺序很重要。因此,我不认为将其转换为集合是合适的。我不想失去元素的顺序。我只是在更改列表中已经重复的元素

另一个例子是

[0, 1, 2, 7, 3, 4, 3, 2, 1]
将成为

[0, 5, 6, 7, 8, 4, 3, 2, 1]
这里发生的事情是,我在索引1处看到了数字1,并且意识到从0到8的范围内,我错过了数字5。所以1被5取代了。同样地,我对索引2也这样做了,我将其替换为6。最后,我对索引4做了这项工作,它最初是3,但被替换为8,因为它是重复的


我的想法是增加重复的数字,然后检查它是否重复,并重复,直到列表中的每个元素都是唯一的。然而,我想不出一个办法来做到这一点

因此,除非我弄错了,否则在你选择替换的数字背后没有真正的方法,只是你认为缺少的一个。如果是这种情况,那么这将产生所需的结果

l = [0, 1, 2, 7, 3, 4, 3, 2, 1]
missing = [n for n in range(len(l)) if n not in set(l)]

for num in l:
    if l.count(num) > 1:
        ix = l.index(num)
        try:
            l[ix] = missing.pop(0)
        except IndexError:
            break

print l
>>[0, 5, 6, 7, 8, 4, 3, 2, 1]

更新:这可以通过查找给定条件的索引来实现

import itertools as it
import collections as ct

from more_itertools import locate 


def replace_repeated(lst):
    """Return a list of unique values with a range ~ list size."""

    def excluded_indices():
        """Yield indices of all but the index of the last repeated element."""
        for i, n in repeated.items():
            yield from it.islice(locate(lst, pred=lambda x: x == i), 0, n-1)

    repeated = {k:v for k, v in ct.Counter(lst).items() if v > 1}
    missing = (i for i, _ in enumerate(lst) if i not in set(lst))
    for i in excluded_indices():
        lst[i] = next(missing)
    return lst
台阶

  • lst
    中查找所有重复元素的值(
    k
    )和频率(
    v
  • 查找与
    lst
    大小成比例的范围内的所有缺失数字
  • 查找
    排除的\u索引
    -重复的
    元素的索引(每个
    重复的
    值的最终出现除外)
  • 对于每个排除的索引,用下一个
    缺失的
    编号覆盖
    lst
    中的元素
  • 测验

    (可选)以下是的代码,如果需要,可以直接实现并避免pip安装:

    def locate(iterable, pred=bool):
        return it.compress(it.count(), map(pred, iterable))
    

    您需要分两个阶段来完成这项工作(或者让其他人分两个阶段来完成)——首先找到缺少的值,然后浏览列表,用缺少的值替换重复的值。比如:

    def normalize_list(data):
        # data = list(data)  # uncomment if you don't want to modify the source list
        # use xrange() instead of range() on Python 2.x
        missing_keys = [i for i in range(len(data)-1, -1, -1) if i not in set(data)]
        for index, value in enumerate(data):
            try:
                if data.index(value, index+1):
                    data[index] = missing_keys.pop()
            except ValueError:
                pass
        return data
    
    print(normalize_list([0, 1, 6, 7, 5, 4, 3, 2, 1]))
    # prints: [0, 8, 6, 7, 5, 4, 3, 2, 1]
    print(normalize_list([0, 1, 2, 7, 3, 4, 3, 2, 1]))
    # prints: [0, 5, 6, 7, 8, 4, 3, 2, 1]
    
    这应该适用于任何大小的列表

    更新

    考虑到
    list.index()
    的缓慢性,这里有一个没有它的版本-它看起来有点不直观(多了一个循环),但是它比第一个示例快了近4倍(列表越长,相对于第一个示例,它的速度就越快),并且内存使用稍微多一些:

    def normalize_list(data):
        # data = list(data)  # uncomment if you don't want to modify the source list
        key_lookup = dict.fromkeys(data, -1)
        # use xrange() instead of range() on Python 2.x
        missing_keys = [i for i in range(len(data)-1, -1, -1) if i not in key_lookup]
        for i in data:
            key_lookup[i] += 1
        for index, value in enumerate(data):
            try:
                if key_lookup[value]:
                    data[index] = missing_keys.pop()
                    key_lookup[value] -= 1
            except ValueError:
                pass
        return data
    

    以下是另一种方法:

  • 计算一个字典,存储列表中每个唯一值的最后一个出现索引
  • 创建缺少值的生成器
  • 使用列表理解替换列表中每个唯一元素的所有值(最后一个值除外)
  • e、 g


    顺序重要吗?请展示您的尝试。您听说过
    集合
    类吗?列表中的元素数是否始终与最大值相同?如果存在多个重复,会发生什么情况?是否始终要替换第一个或最后一个元素?我的观点是,这是一个非常不明确的问题,你应该在提问之前对你的问题进行更多的思考。如果您花时间精确地说明需求,您可能会自己想出一个答案。这些需求没有正确地指定。请添加更多详细信息。为什么要在每个循环中重建
    缺失的
    列表?听起来很低效。另外,与列表生成相反,
    list.pop()
    要比
    list.pop(0)
    快得多。哎呀,
    缺失
    不属于循环,好的捕获方法非常有趣。。。效率很低,需要安装额外的模块,tho…@zwer谢谢您的评论。我为那些对
    pip安装more\u itertools
    不感兴趣的人添加了实现,因此它不依赖于任何安装。至于效率,我相信你的例子不会更快,尽管这是一个有趣的变化。因此,我不确定你的意思。相当低效==将以非最佳方式运行。此外,它不会产生期望的输出-第一个输出大约是唯一一个符合OP要求的输出。仍然有点模糊,但我改进了您发现的清晰点。谢谢
    def normalize_list(data):
        # data = list(data)  # uncomment if you don't want to modify the source list
        key_lookup = dict.fromkeys(data, -1)
        # use xrange() instead of range() on Python 2.x
        missing_keys = [i for i in range(len(data)-1, -1, -1) if i not in key_lookup]
        for i in data:
            key_lookup[i] += 1
        for index, value in enumerate(data):
            try:
                if key_lookup[value]:
                    data[index] = missing_keys.pop()
                    key_lookup[value] -= 1
            except ValueError:
                pass
        return data
    
    xs = [0, 1, 6, 7, 5, 4, 3, 2, 1]
    fixed  = {x: i for i, x in enumerate(xs)}
    spares = iter(x for x in range(len(xs)) if x not in fixed)
    res    = [x if i == fixed[x] else next(spares)
                for i, x in enumerate(xs)]
    
    def returnModifiedList(x):
    
     #find indices where there is a repeat
     storage=[]; indices = []
     for i in range(len(x)-1,-1,-1):
         if x[i] in storage:
             indices.append(i)
         else:
             storage.append(x[i])
    
     #find values that are missing
     s = sorted(list(set(x)))
     missing = list(reversed([i for i in range(len(x)) if (i not in s)]))
    
     #fill in repeats with missing values
     for i in range(len(indices)):
         x[indices[i]] = missing[i]
    
     return x
    
    
    
    x = [0, 1, 2, 7, 3, 4, 3, 2, 1]
    results = returnModifiedList(x)
    print results