Найти повторяющийся элемент во вложенном списке - PullRequest
0 голосов
/ 17 сентября 2018

У меня есть вложенный список элементов:

employee_list =  [
    ['Name', '=', 'John'],
    ['Age', '=', '32'],
    ['Weight', '=', '60'],
    ['Name', '=', 'Steve'],
    ['Weight', '=', '85']
]

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

unique_list = [['Age', '=', '32']]

repeated_list = [
    ['Name', '=', 'John'],
    ['Weight', '=', '60'],
    ['Name', '=', 'Steve'],
    ['Weight', '=', '85']
] 

Уникальность или повторяемость определяется первым элементом каждого подсписка. Например: 'Name', 'Weight'. Если есть два подсписка, где первый элемент - 'Name', я считаю его повторением.

Кто-нибудь может предложить простой способ сделать это?

Ответы [ 5 ]

0 голосов
/ 17 сентября 2018

Я использую чистое решение (я добавил еще одну строку, чтобы сделать его более общим):

Допустим, это наши данные:

data = np.array(data).astype(str)

data: array([['Name', '=', 'John'],
       ['Age', '_', '32'],
       ['Weight', '=', '60'],
       ['Name', '=', 'John'],
       ['Weight', '=', '60'],
       ['TT', '=', 'EE']], dtype='<U6')

Следующий шаг - захват уникальных строк:

uniq = np.unique(data, axis=0)
uniq: array([['Age', '_', '32'],
       ['Name', '=', 'John'],
       ['TT', '=', 'EE'],
       ['Weight', '=', '60']], dtype='<U6')

Теперь мы хотим увидеть, какие строки не повторяются более одного раза: (Ответ только для однократных строк:)

only_once = np.array([row for row in uniq if sum(np.all(row==data, axis=1)) == 1])
only_once:
array([['Age', '_', '32'],
       ['TT', '=', 'EE']], dtype='<U6')

Чтобы получить повторные индексы:

idx = []
for row in only_once:
    lst = np.all(data==row, axis=1)
    idx = np.where(lst)[0]
    idx.append(idx)
idx:
[array([1]), array([5])]

Матрица только повторяющихся значений:

result = np.delete(data, idx, axis=0)
result:
array([['Name', '=', 'John'],
       ['Weight', '=', '60'],
       ['Name', '=', 'John'],
       ['Weight', '=', '60']], dtype='<U6')
0 голосов
/ 17 сентября 2018

Если вы создали test_list, который содержит все items в employee_list, вы можете использовать встроенный метод count и count появления каждого employee_list[i][0] в этом list, еслиcount == 1 затем мы добавляем все это item к нашему unique_list

employee_list =  [
    ['Name', '=', 'John'],
    ['Age', '=', '32'],
    ['Weight', '=', '60'],
    ['Name', '=', 'Steve'],
    ['Weight', '=', '85']
]

unique_list = []
repeated_list = [] 
test_list = []

for i in employee_list:
    for j in i:
        test_list.append(j)

for i in employee_list:
    if test_list.count(i[0]) == 1:
        unique_list.append(i)
    else:
        repeated_list.append(i)

print(f"Repeated: {repeated_list}")
print(f"Unique: {unique_list}")
(xenial)vash@localhost:~/python/stack_overflow$ python3.7 unique.py 
Repeated: [['Name', '=', 'John'], ['Weight', '=', '60'], ['Name', '=', 'Steve'], ['Weight', '=', '85']]
Unique: [['Age', '=', '32']]
0 голосов
/ 17 сентября 2018

Вы можете использовать collections.Counter и понять два списка на основе количества значимых первых элементов:

from collections import Counter

c = Counter(l[0] for l in employee_list)
# Counter({'Name': 2, 'Weight': 2, 'Age': 1})

uniq = [l for l in employee_list if c[l[0]] == 1]
# [['Age', '=', '32']]

rept = [l for l in employee_list if c[l[0]] > 1]
# [['Name', '=', 'John'],
#  ['Weight', '=', '60'],
#  ['Name', '=', 'Steve'],
#  ['Weight', '=', '85']]

Обновление: split rept по «ключу»

d = {}
for l in rept:
    d.setdefault(l[0], []).append(l)
list(d.values())
# [[['Name', '=', 'John'], ['Name', '=', 'John']],
#  [['Weight', '=', '60'], ['Weight', '=', '60']]]
0 голосов
/ 17 сентября 2018

Существует множество решений, которые вы можете использовать, включая списки и фильтры. Вы также можете использовать наборы и список для создания уникального набора элементов и преобразования обратно в список, как показано в ссылке , предоставленной benvc Затем, после того как вы получите список уникальных элементов, вы можете отфильтровать эти элементы из исходного списка, чтобы получить результирующий список дубликатов (если есть)

См. советы по питону на фильтре

0 голосов
/ 17 сентября 2018

Вы не можете использовать список списка, чтобы сделать Counter, он вернет

тип unhashable: 'список'

Так что нам нужно конвертировать в list из tuple

employee_tuple=list(map(tuple,employee_list))
# then we using Counter    
from collections import Counter
d=Counter(employee_tuple)

l=list(map(d.get,employee_tuple))# get the freq of each item
l
Out[372]: [2, 1, 2, 2, 2]

# then we using filter 
from itertools import compress
list(compress(employee_list, map(lambda x: x == 1, l)))
Out[380]: [['Age', '=', '32']]


list(compress(employee_list, map(lambda x: x != 1, l)))
Out[384]: 
[['Name', '=', 'John'],
 ['Weight', '=', '60'],
 ['Name', '=', 'John'],
 ['Weight', '=', '60']]
...