Удаление элементов списка, которые состоят из одинаковых номеров - PullRequest
0 голосов
/ 12 февраля 2019

У меня есть программа на 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 голосов
/ 12 февраля 2019

вы можете перебрать свой список и добавить каждый элемент в набор, прежде чем добавлять свой элемент в набор, вы должны проверить, существует ли элемент / обратный элемент.Это устранит вашу проблему

my_list = ['0007', '7000']
final = set()
for item in my_list:
    if item not in final and item[::-1] not in final:
        final.add(item)
final = list(final)
print(final) 
# output: ['0007']
0 голосов
/ 12 февраля 2019

Использование set для проверки, если уже посещено при сохранении заказа.Он отфильтрует элементы, которые мы уже видели, прежде чем считать '0007' и '7000' одинаковыми, и в наборе мы можем сохранить количество 0 и 7 вместо самого элемента

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']
0 голосов
/ 12 февраля 2019

Если вы не возражаете, заканчивая списком элементов в другом порядке, вот идея:

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']
0 голосов
/ 12 февраля 2019

Вы должны преобразовать свои элементы во что-то, что будет равным для таких входов, как "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 не подлежат уничтожению (как жаль).Таким образом, вы можете использовать кортежную версию счетчиков:

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 с, который будетвыглядите и ведите себя как обычные строки, так что вы, вероятно, можете использовать их для всего, что хотите с ними сделать сразу.

0 голосов
/ 12 февраля 2019

Вы можете использовать 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)
0 голосов
/ 12 февраля 2019

Используйте 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']
...