删除列表元素而不是由相同数字组成的

时间:2019-02-12 15:50:59

标签: python list duplicates

我有一个python程序,输出如下所示的列表:

['0007', '0016', '0025', '0034', '0043', '0052', '0061', '0070', '0106', '0115', '0124', '0133', '0142', '0151', '0160', '0205', '0214', '0223', '0232', '0241', '0250', '0304', '0313', '0322', '0331', '0340', '0403', '0412', '0421', '0430', '0502', '0511', '0520', '0601', '0610', '0700', '1006', '1015', '1024', '1033', '1042', '1051', '1060', '1105', '1114', '1123', '1132', '1141', '1150', '1204', '1213', '1222', '1231', '1240', '1303', '1312', '1321', '1330', '1402', '1411', '1420', '1501', '1510', '1600', '2005', '2014', '2023', '2032', '2041', '2050', '2104', '2113', '2122', '2131', '2140', '2203', '2212', '2221', '2230', '2302', '2311', '2320', '2401', '2410', '2500', '3004', '3013', '3022', '3031', '3040', '3103', '3112', '3121', '3130', '3202', '3211', '3220', '3301', '3310', '3400', '4003', '4012', '4021', '4030', '4102', '4111', '4120', '4201', '4210', '4300', '5002', '5011', '5020', '5101', '5110', '5200', '6001', '6010', '6100', '7000']

从理论上讲,它不包含任何重复项,但包含诸如'0007'和'7000'之类的元素,它们由相同的元素(3个零和1个七个)组成,标准过滤脚本不会捕获它们。如何制作一个比将其删除? 咨询后,我们发现不需要保留订单,因此,您的解决方案效果很好,谢谢

(如果我的帖子重复,那么很抱歉,但我找不到相同的问题。请为一个问题提供解决方案)

6 个答案:

答案 0 :(得分:3)

使用set()消除重复项,然后使用sorted()用原始列表顺序对其进行排序。

l = ['0007', '0016', '0025', '0034', '0043', '0052', '0061', '0070', '0106', '0115',  '0124', '0133', '0142', '0151', '0160', '0205', '0214', '0223', '0232', '0241', '0250', '0304', '0313', '0322', '0331', '0340', '0403', '0412', '0421', '0430', '0502', '0511', '0520', '0601', '0610', '0700', '1006', '1015', '1024', '1033', '1042', '1051', '1060', '1105', '1114', '1123', '1132', '1141', '1150', '1204', '1213', '1222', '1231', '1240', '1303', '1312', '1321', '1330', '1402', '1411', '1420', '1501', '1510', '1600', '2005', '2014', '2023', '2032', '2041', '2050', '2104', '2113', '2122', '2131', '2140', '2203', '2212', '2221', '2230', '2302', '2311', '2320', '2401', '2410', '2500', '3004', '3013', '3022', '3031', '3040', '3103', '3112', '3121', '3130', '3202', '3211', '3220', '3301', '3310', '3400', '4003', '4012', '4021', '4030', '4102', '4111', '4120', '4201', '4210', '4300', '5002', '5011', '5020', '5101', '5110', '5200', '6001', '6010', '6100', '7000']

sorted(list(set(''.join(sorted(x)) for x in l)), key=lambda x: l.index(x))

# ['0007', '0016', '0025', '0034', '0115', '0124', '0133', '0223', '1114', '1123', '1222']

答案 1 :(得分:2)

如果您不介意以不同顺序的元素列表结尾,这是一个主意:

lst = [ ... your input ... ]
uniques = list({''.join(sorted(n)) for n in lst})

说明:

  • 输入中的每个字符串均被视为字符的排序列表,以将相同组合以不同顺序视同大小写
  • 之后,我们将每个列表重新组合成一个字符串
  • 我们通过设定理解力删除重复项
  • 最后,我们将所有内容转换回列表

结果如下:

['0016', '0124', '1222', '0115', '0034', '0025', '0223', '0007', '1123', '1114', '0133']

如果您确实只想保留元素的第一次出现,我们可以这样做,但是会降低性能:

result = []
for n in lst:
    unique = ''.join(sorted(n))
    if unique not in result:
        result.append(n)

result
=> ['0007', '0016', '0025', '0034', '0115', '0124', '0133', '0223', '1114', '1123', '1222']

答案 2 :(得分:1)

对于诸如"0007""7000"之类的输入,应将元素转换为等于 的元素。首先想到的是一个计数器。然后将元素放入set()中,这将删除所有双打:

from collections import Counter

input_elements = ['0007', '0016', '0025', '0034', '0043', '0052', '0061',
                  '0070', '0106', '0115', '0124', '0133', '0142', '0151',
                  '0160', '0205', '0214', '0223', '0232', '0241', '0250',
                  # ...
                  '7000']
s = set(Counter(e) for e in input_elements)

现在s将包含一组所有input_elements,其中删除了双打。

不幸的是,Counter无法散列(真可惜)。因此,您可以使用计数器的元组版本:

s = set(tuple(Counter(e).items()) for e in input_elements)

我能想到的最漂亮的方法是创建自己的字符串类,该字符串类具有此特定属性,当它们具有相同的数字时,不管它们的顺序如何,它们都被视为相等:

class OrderIrrelevantString(str):
  def __hash__(self):
    return hash(''.join(sorted(self)))
  def __eq__(self, other):
    return sorted(self) == sorted(other)

使用此功能,您可以像这样操作:

s = set(OrderIrrelevantString(e) for e in input_elements)

然后,结果将是一组OrderIrrelevantString,它们的外观和行为类似于普通的字符串,因此您可以立即将它们用于您想对其进行处理的任何事情。

答案 3 :(得分:0)

您可以使用sorted按照字典顺序对字符串进行排序,以创建唯一的条目,然后可以将其存储在字典中以进行快速查找

some_filter = {} # will create a lookup table for unique combinations of chars
filtered_results = [] # contain the final results

for x in result:
    hashable = "".join(sorted(x))
    if not some_filter.get(hashable):
        filtered_results.append(x)
        some_filter[hashable] = True

print(filtered_results)

答案 4 :(得分:0)

在维护订单的同时,使用set检查是否已访问过。在考虑'0007''7000'相同之前,它将过滤掉已经看到的元素,并且在集合中,我们可以保留07的计数,而不是元素本身

l = ['0007', '0016', '0025', '0034', '0043', '0052', '0061', '0070', '0106', '0115',  '0124', '0133', '0142', '0151', '0160', '0205', '0214', '0223', '0232', '0241', '0250', '0304', '0313', '0322', '0331', '0340', '0403', '0412', '0421', '0430', '0502', '0511', '0520', '0601', '0610', '0700', '1006', '1015', '1024', '1033', '1042', '1051', '1060', '1105', '1114', '1123', '1132', '1141', '1150', '1204', '1213', '1222', '1231', '1240', '1303', '1312', '1321', '1330', '1402', '1411', '1420', '1501', '1510', '1600', '2005', '2014', '2023', '2032', '2041', '2050', '2104', '2113', '2122', '2131', '2140', '2203', '2212', '2221', '2230', '2302', '2311', '2320', '2401', '2410', '2500', '3004', '3013', '3022', '3031', '3040', '3103', '3112', '3121', '3130', '3202', '3211', '3220', '3301', '3310', '3400', '4003', '4012', '4021', '4030', '4102', '4111', '4120', '4201', '4210', '4300', '5002', '5011', '5020', '5101', '5110', '5200', '6001', '6010', '6100', '7000']

from collections import Counter
s=set()
new_list=[]
for i in l:
    if tuple(Counter(sorted(i,key=int)).items()) in s:
        pass
    else:
        s.add(tuple(Counter(sorted(i,key=int)).items()))
        new_list.append(i)

输出:

['0007',
 '0016',
 '0025',
 '0034',
 '0115',
 '0124',
 '0133',
 '0223',
 '1114',
 '1123',
 '1222']

答案 5 :(得分:0)

您可以遍历列表并将每个元素添加到集合中,然后再将元素添加到集合中,您应该检查元素/反向元素是否已经存在。这将消除您的问题

WS_BORDER