Удаление повторяющихся значений и определение того, какой ключ имеет наибольшее количество значений в python - PullRequest
0 голосов
/ 08 октября 2018

У меня есть этот код, который получает информацию из текстового файла со значениями, такими как key1: value1 и т. Д., Но некоторые из них представлены несколько раз под ключом 1.Как я могу удалить дубликаты и после этого, как я могу отсортировать, какой ключ имеет наибольшее и наименьшее значения?

def function1(file):
    with open("file_name.txt") as file:
        name = file.read()
    d = {}
    for x in name.split():
        key, value = x.split(':')
        try:
            values = d[key]
        except KeyError:
            values = d[key] = []
        values.append(value)
    return d

Ответы [ 3 ]

0 голосов
/ 08 октября 2018

Посмотрите в модуль счетчика:

from collections import Counter
x = Counter(mylist)
print x
0 голосов
/ 08 октября 2018

Одним из улучшений по сравнению с вашим кодом является то, что я использовал defaultdict, автоматически генерируя значение для несуществующего ключа.

Еще одним улучшением является разделение с использованием re.split, поэтому строка ввода может иметьдвоеточие, окруженное пробелами.

Важной деталью в вашем вопросе является то, что вы хотите посчитать значения без повторений (как я полагаю, отдельно для каждого ключа).Таким образом, программа должна:

  • проверить, было ли определенное значение уже сохранено под текущим ключом,
  • сохранить текущее значение (добавить в список), только если оно не произошлоbefore.

Таким образом, использование Counter, на мой взгляд, не очень хорошая идея, поскольку оно подсчитывает, сколько раз значение было повторено , независимо от ключа, под которымэто произошло, тогда как мы должны посчитать, сколько различных значений было прочитано под каждой клавишей.

В следующей программе:

  • filterValues ​​ функция читает строки из входного файла, сохраняет массивы значений под текущим ключом и возвращает словарь,
  • findMinMax функция находит 2 кортежа (список ключ / значение), один для списка сокращенийи еще один для самого длинного.

Вот код:

from collections import defaultdict
import re

def filterValues(fn):
    with open(fn) as file:
        lines = file.readlines()
    d = defaultdict(list)  # key -> values
    for line in lines:
        key, value = re.split('\s*:\s*',line.strip())
        values = d[key]
        if value not in values:  # Save value, w/o repetitions
            values.append(value)
    return d

def findMinMax(d):
    t1 = min(d.items(), key=lambda x: len(x[1]))
    t2 = max(d.items(), key=lambda x: len(x[1]))
    return t1, t2

d = filterValues('file_name.txt')
print(dict(d))
t1, t2 = findMinMax(d)
print(f'Min. count: {len(t1[1])}: {t1[0]} -> {t1[1]}')
print(f'Max. count: {len(t2[1])}: {t2[0]} -> {t2[1]}')

Для следующего примера ввода:

K1 : V1
K1 : V2
K1 : V3
K1 : V1
K1 : V4
K1 : V1
K1 : V4
K2 : V5
K2 : V6
K2 : V6
K2 : V6
K3 : V2
K4 : V5

он печатает:

{'K1': ['V1', 'V2', 'V3', 'V4'], 'K2': ['V5', 'V6'], 'K3': ['V2'], 'K4': ['V5']}
Min. count: 1: K3 -> ['V2']
Max. count: 4: K1 -> ['V1', 'V2', 'V3', 'V4']
0 голосов
/ 08 октября 2018

Предполагая, что у вас есть входные данные, такие как:

lines = '''
key1:val1
key2:val2
key3:val3
key1:val4
key1:val5
key2:val6
'''.strip().split()

Что-то вроде этого должно помочь вам начать:

from collections import defaultdict

d = defaultdict(list)

for line in lines:
    k,v = line.split(':')
    d[k].append(v)

items = sorted(d.items(), key=lambda i:len(i[1]))
print(items)

Вывод (отсортировано по наименьшему большинству значений, добавьте reverse=True к sort для большинства к наименьшему)

[
  ('key3', ['val3']), 
  ('key2', ['val2', 'val6']), 
  ('key1', ['val1', 'val4', 'val5'])
]
...