Как сгруппировать одинаковые значения из списка в их собственные списки? - PullRequest
0 голосов
/ 22 ноября 2018

Скажем, у меня есть список [2, 3, 7, 2, 3, 8, 7, 3]

Я хотел бы создать списки, которые содержат идентичные значения из списка выше.

Ожидаемый результат Что-то вроде:

[2, 2]
[3, 3, 3]
[7, 7]
[8]

Порядок создания этих списков не имеет значения.

Ответы [ 7 ]

0 голосов
/ 22 ноября 2018

Этот ответ с списком :

l = [2, 3, 7, 2, 3, 8, 7, 3]

print(*[[i]*l.count(i) for i in set(l)], sep='\n')

ВЫХОД:

C:\Users\Desktop>py x.py
[8]
[2, 2]
[3, 3, 3]
[7, 7]

Более того, вывод может быть сделан точно так же, как ваш, с помощью sorted() метода

l = [2, 3, 7, 2, 3, 8, 7, 3]

print(*sorted([[i]*l.count(i) for i in set(l)]), sep='\n')

ВЫХОД:

C:\Users\Desktop>py x.py
[2, 2]
[3, 3, 3]
[7, 7]
[8]

РЕДАКТИРОВАТЬ: Какответ получен, и я хочу объяснить код подробно, чтобы быть максимально полезным.

Код такой:

 print(*[[i]*l.count(i) for i in set(l)], sep='\n')

Использование set(l) устраняет дублирующиеся значения и остается только[2, 3, 7, 8] в списке.Позже, в [i] мы поместили каждый элемент set(l) в новый список.Мы подсчитываем, сколько раз элемент i (i является элементом в set(l)) встречается в собственном списке l (l = [2, 3, 7, 2, 3, 8, 7, 3]).И в [i]*l.count(i) i становятся l.count(i) раз в новом списке.Метод осмысления списка получает все значения после выполнения итераций, упаковывает их в список и возвращает список.Знак * в начале предназначен для распаковки значений в возвращаемом списке.И наконец *print()* ключевое слово sep='\n' ставьте '\n' после каждого элемента в распакованном списке.Без этого это можно было бы сделать так:

for j in [[i]*l.count(i) for i in set(l)]:
    print(j)
0 голосов
/ 22 ноября 2018

Один из способов сделать это - использовать простой словарь :

l = [2, 3, 7, 2, 3, 8, 7, 3]

groups = {}
for n in l:
    groups.setdefault(n, []).append(n)

print(list(groups.values()))
# [[2, 2], [3, 3, 3], [7, 7], [8]]
0 голосов
/ 22 ноября 2018

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

from collections import Counter
l = [2, 3, 7, 2, 3, 8, 7, 3]
c =Counter(l)
print(c) ## result: {3: 3, 2: 2, 7: 2, 8: 1} 
0 голосов
/ 22 ноября 2018

Лучший подход - это решение O(n) с collections.defaultdict:

>>> l = [2, 3, 7, 2, 3, 8, 7, 3]
>>> d = defaultdict(list)
>>> for e in l:
...     d[e].append(e)
... 
>>> d
defaultdict(<class 'list'>, {2: [2, 2], 3: [3, 3, 3], 7: [7, 7], 8: [8]})
>>> d.values()
dict_values([[2, 2], [3, 3, 3], [7, 7], [8]])

В качестве альтернативы вы можете использовать itertools.groupby с отсортированным списком:

>>> for _, l in itertools.groupby(sorted(l)):
...     print(list(l))
... 
[2, 2]
[3, 3, 3]
[7, 7]
[8]

Или понимание списка с помощью collections.Counter:

>>> from collections import Counter
>>> [[i]*n for i,n in Counter(l).items()]
[[2, 2], [3, 3, 3], [7, 7], [8]]

Когда я публикую пост, решение defaultdict будет O(n) и быстрее, чем другие подходы.Вот тесты:

from timeit import timeit


setup = (
"from collections import Counter, defaultdict;"
"from itertools import groupby;"
"l = [2, 3, 7, 2, 3, 8, 7, 3];"
)

defaultdict_call = (
"d = defaultdict(list); "
"\nfor e in l: d[e].append(e);"
)
groupby_call = "[list(g) for _,g in groupby(sorted(l))]"
counter_call = "[[i]*n for i,n in Counter(l).items()]"


for call in (defaultdict_call, groupby_call, counter_call):
  print(call)
  print(timeit(call, setup))

Результаты:

d = defaultdict(list); 
for e in l: d[e].append(e);
7.02662614302244
[list(g) for _,g in groupby(sorted(l))]
10.126392606005538
[[i]*n for i,n in Counter(l).items()]
19.55539561196929

Вот живой тест

0 голосов
/ 22 ноября 2018

Вот короткий способ сделать это с помощью Counter

from collections import Counter
my_dict = Counter([2, 3, 7, 2, 3, 8, 7, 3]) # returns {3: 3, 2: 2, 7: 2, 8: 1}

new_list = [[k] * v for k,v in my_dict.items()] 

Выходы:

[[2, 2], [3, 3, 3], [7, 7], [8]]
0 голосов
/ 22 ноября 2018

Выполнение этой операции в массиве Numpy будет эффективным

a= np.array([2, 3, 7, 2, 3, 8, 7, 3])
[a[a==i] for i in np.unique(a)]

Вывод:

[array([2, 2]), array([3, 3, 3]), array([7, 7]), array([8])]
0 голосов
/ 22 ноября 2018

Попробуйте это

l = [2, 3, 7, 2, 3, 8, 7, 3]
for i in set(l):
   print([i]*l.count(i))

Вывод:

[8]
[2, 2]
[3, 3, 3]
[7, 7]
...