@Питер. Да, вы отсортировали список для публикации. Будет ли список всегда сортироваться?
С.Лотт
2
Нет, список не будет отсортирован всегда. Это не домашняя работа.
Брюс
Я пытаюсь построить график распределения степени сети.
Брюс
5
@Peter: Пожалуйста, обновите ваш вопрос с полезной информацией. Пожалуйста, не добавляйте комментарии к своему вопросу - вы являетесь владельцем вопроса, вы можете исправить его, чтобы он был полным и понятным.
С.Лотт
Ответы:
147
Примечание: вы должны отсортировать список перед использованием groupby.
Вы можете использовать groupbyиз itertoolsпакета, если список является упорядоченным списком.
a =[1,1,1,1,2,2,2,2,3,3,4,5,5]from itertools import groupby[len(list(group))for key, group in groupby(a)]
здорово, используя groupby. Интересно, насколько он эффективен по сравнению с политическим подходом
Эли Бендерский
32
Python groupby создает новые группы, когда значение, которое он видит, изменяется. В этом случае 1,1,1,2,1,1,1] вернется [3,1,3]. Если вы ожидали [6,1], то просто убедитесь, что отсортировали данные перед использованием groupby.
Эван
4
@CristianCiupitu: sum(1 for _ in group).
Мартин Питерс
6
Это не решение. Вывод не говорит, что было посчитано.
Buhtz
8
[(key, len(list(group))) for key, group in groupby(a)]или {key: len(list(group)) for key, group in groupby(a)}@buhtz
@unutbu: Что делать, если у меня есть три списка, a, b, c, для которых a и b остаются неизменными, но c изменяется? Как посчитать значение c, для которого a и c одинаковы?
ThePredator
@ Шриватсан: я не понимаю ситуацию. Пожалуйста, разместите новый вопрос, где вы можете уточнить.
unutbu
1
Есть ли способ извлечь словарь {1: 4, 2: 4, 3: 2, 5: 2, 4: 1} из объекта счетчика?
Паван
7
@Pavan: collections.Counterэто подкласс dict. Вы можете использовать его так же, как и обычный диктат. Если вы действительно хотите диктовку, вы можете преобразовать ее в диктовку, используя dict(counter).
Unutbu
1
Работает в 3.6 также, поэтому предположим, что больше 2.7
kpierce8
108
Python 2.7+ вводит понимание словаря. Сборка словаря из списка позволит вам подсчитать и избавиться от дубликатов.
>>> a =[1,1,1,1,2,2,2,2,3,3,4,5,5]>>> d ={x:a.count(x)for x in a}>>> d
{1:4,2:4,3:2,4:1,5:2}>>> a, b = d.keys(), d.values()>>> a
[1,2,3,4,5]>>> b
[4,4,2,1,2]
Это очень хорошо работает со списками строк, а не целыми числами, как в оригинальном вопросе.
Глен Селле
15
Это быстрее с использованием набора:{x:a.count(x) for x in set(a)}
stenci
45
Это крайне неэффективно . a.count()делает полный ход для каждого элемента в a, делая это O (N ^ 2) квадрадическим подходом. collections.Counter()является гораздо более эффективным , поскольку он рассчитывает линейное время (O (N)). В цифрах это означает, что этот подход будет выполнять 1 миллион шагов для списка длиной 1000, а не только 1000 шагов с Counter(), 10 ^ 12 шагов, где счетчику требуется только 10 ^ 6 для миллиона элементов в списке и т. Д.
Мартейн Питерс
3
@stenci: конечно, но ужас от использования a.count()полностью снижает эффективность использования набора.
Мартин Питерс
2
@MartijnPieters еще одна причина, чтобы использовать его меньше раз :)
stenci
48
Для подсчета количества появлений:
from collections import defaultdict
appearances = defaultdict(int)for curr in a:
appearances[curr]+=1
@phkahler: Мой будет только чуть-чуть лучше, чем этот. Вряд ли стоит публиковать отдельный ответ, когда его можно улучшить с небольшими изменениями. Смысл SO в том, чтобы найти лучшие ответы. Я мог бы просто отредактировать это, но я предпочитаю дать первоначальному автору шанс внести свои собственные улучшения.
С.Лотт
1
@ S.Lott Код намного чище без необходимости импорта defaultdict.
bstrauch24
Почему не preinitialize б: b = {k:0 for k in a}?
DylanYoung
20
Вот еще одна альтернатива succint, itertools.groupbyкоторая также работает для неупорядоченного ввода:
from itertools import groupby
items =[5,1,1,2,2,1,1,2,2,3,4,3,5]
results ={value: len(list(freq))for value, freq in groupby(sorted(items))}
Хотя этот фрагмент кода может быть решением, включение объяснения действительно помогает улучшить качество вашего сообщения. Помните, что вы отвечаете на вопрос читателей в будущем, и эти люди могут не знать причин, по которым вы предлагаете свой код
Рахул Гупта
Да будет делать это Рахул Гупта
Анирбан Лахири
7
seta = set(a)
b =[a.count(el)for el in seta]
a = list(seta)#Only if you really want it.
использование списков countсмехотворно дорого и неуместно в этом сценарии.
Идан К
@IdanK почему считать дорого?
Критика Раджайн
@KritikaRajain Для каждого уникального элемента в списке вы выполняете итерацию по всему списку для генерации счетчика (квадратичного числа уникальных элементов в списке). Вместо этого вы можете перебирать список один раз и подсчитывать количество каждого уникального элемента (линейно по размеру списка). Если в вашем списке есть только один уникальный элемент, результат будет таким же. Более того, этот подход требует дополнительного промежуточного набора.
DylanYoung
7
Я бы просто использовал scipy.stats.itemfreq следующим образом:
from scipy.stats import itemfreq
a =[1,1,1,1,2,2,2,2,3,3,4,5,5]
freq = itemfreq(a)
a = freq[:,0]
b = freq[:,1]
a =[1,1,1,1,2,2,2,2,3,3,3,4,4]
d ={}for item in a:if item in d:
d[item]= d.get(item)+1else:
d[item]=1for k,v in d.items():print(str(k)+':'+str(v))# output#1:4#2:4#3:3#4:2#remove dups
d = set(a)print(d)#{1, 2, 3, 4}
a =[1,1,1,1,2,2,2,2,3,3,4,5,5]# 1. Get counts and store in another list
output =[]for i in set(a):
output.append(a.count(i))print(output)# 2. Remove duplicates using set constructor
a = list(set(a))print(a)
Набор коллекций не допускает дублирования, передача списка конструктору set () даст итерируемые полностью уникальные объекты. Функция count () возвращает целое число при передаче объекта, который находится в списке. При этом подсчитываются уникальные объекты, и каждое значение счетчика сохраняется путем добавления к выводу пустого списка.
Конструктор list () используется для преобразования набора (a) в список и ссылается на ту же переменную a
def frequency(l):
d ={}for i in l:if i in d.keys():
d[i]+=1else:
d[i]=1for k, v in d.iteritems():if v ==max (d.values()):return k,d.keys()print(frequency([10,10,10,10,20,20,20,20,40,40,50,50,30]))
max(d.values())не изменится в последнем цикле. Не вычисляйте это в цикле, вычисляйте это перед циклом.
DylanYoung
1
#!usr/bin/pythondef frq(words):
freq ={}for w in words:if w in freq:
freq[w]= freq.get(w)+1else:
freq[w]=1return freq
fp = open("poem","r")
list = fp.read()
fp.close()
input = list.split()print input
d = frq(input)print"frequency of input\n: "print d
fp1 = open("output.txt","w+")for k,v in d.items():
fp1.write(str(k)+':'+str(v)+"\n")
fp1.close()
num=[3,2,3,5,5,3,7,6,4,6,7,2]print('\nelements are:\t',num)
count_dict={}for elements in num:
count_dict[elements]=num.count(elements)print('\nfrequency:\t',count_dict)
Пожалуйста, не публикуйте ответы только для кода, а уточняйте код, особенно если на вопрос уже есть действительный ответ.
Erik A
1
from collections importOrderedDict
a =[1,1,1,1,2,2,2,2,3,3,4,5,5]def get_count(lists):
dictionary =OrderedDict()for val in lists:
dictionary.setdefault(val,[]).append(1)return[sum(val)for val in dictionary.values()]print(get_count(a))>>>[4,4,2,1,2]
Я использую счетчик для генерации частоты. из слов текстового файла в одной строке кода
def _fileIndex(fh):''' create a dict using Counter of a
flat list of words (re.findall(re.compile(r"[a-zA-Z]+"), lines)) in (lines in file->for lines in fh)
'''returnCounter([wrd.lower()for wrdList in[words for words in[re.findall(re.compile(r'[a-zA-Z]+'), lines)for lines in fh]]for wrd in wrdList])
Еще одно решение с другим алгоритмом без использования коллекций:
def countFreq(A):
n=len(A)
count=[0]*n # Create a new list initialized with '0'for i in range(n):
count[A[i]]+=1# increase occurrence for value A[i]return[x for x in count if x]# return non-zero count
>>> L =[1,1,1,1,2,2,2,2,3,3,4,5,5]>>>import functools
>>>>>> functools.reduce(lambda acc, e:[v+(i==e)for i, v in enumerate(acc,1)]if e<=len(acc)else acc+[0for _ in range(e-len(acc)-1)]+[1], L,[])[4,4,2,1,2]
Будет чище, если считать нули тоже:
>>> functools.reduce(lambda acc, e:[v+(i==e)for i, v in enumerate(acc)]if e<len(acc)else acc+[0for _ in range(e-len(acc))]+[1], L,[])[0,4,4,2,1,2]
Объяснение:
мы начинаем с пустого accсписка;
если следующий элемент eиз Lниже , чем размер acc, мы просто обновить этот элемент: v+(i==e)средства , v+1если индекс iв accэто текущий элемент e, в противном случае предыдущее значениеv ;
если следующий элемент eиз Lбольше или равен размеру acc, мы должны расширить accдля размещения нового 1.
Элементы не должны быть отсортированы ( itertools.groupby). Вы получите странные результаты, если у вас есть отрицательные числа.
Нашел другой способ сделать это, используя наборы.
#ar is the list of elements#convert ar to set to get unique elements
sock_set = set(ar)#create dictionary of frequency of socks
sock_dict ={}for sock in sock_set:
sock_dict[sock]= ar.count(sock)
Чтобы найти количество уникальных элементов в отсортированном массиве, используя словарь
defCountFrequency(my_list):# Creating an empty dictionary
freq ={}for item in my_list:if(item in freq):
freq[item]+=1else:
freq[item]=1for key, value in freq.items():print("% d : % d"%(key, value))# Driver function if __name__ =="__main__":
my_list =[1,1,1,5,5,3,1,3,3,1,4,4,4,2,2,2,2]CountFrequency(my_list)
Еще один способ - использовать словарь и list.count, ниже наивного способа сделать это.
dicio = dict()
a =[1,1,1,1,2,2,2,2,3,3,4,5,5]
b = list()
c = list()for i in a:if i in dicio:continueelse:
dicio[i]= a.count(i)
b.append(a.count(i))
c.append(i)print(b)print(c)
Ответы:
Примечание: вы должны отсортировать список перед использованием
groupby
.Вы можете использовать
groupby
изitertools
пакета, если список является упорядоченным списком.Вывод:
источник
groupby
. Интересно, насколько он эффективен по сравнению с политическим подходомsum(1 for _ in group)
.[(key, len(list(group))) for key, group in groupby(a)]
или{key: len(list(group)) for key, group in groupby(a)}
@buhtzВ Python 2.7 (или новее) вы можете использовать
collections.Counter
:Если вы используете Python 2.6 или старше, вы можете скачать его здесь .
источник
collections.Counter
это подклассdict
. Вы можете использовать его так же, как и обычный диктат. Если вы действительно хотите диктовку, вы можете преобразовать ее в диктовку, используяdict(counter)
.Python 2.7+ вводит понимание словаря. Сборка словаря из списка позволит вам подсчитать и избавиться от дубликатов.
источник
{x:a.count(x) for x in set(a)}
a.count()
делает полный ход для каждого элемента вa
, делая это O (N ^ 2) квадрадическим подходом.collections.Counter()
является гораздо более эффективным , поскольку он рассчитывает линейное время (O (N)). В цифрах это означает, что этот подход будет выполнять 1 миллион шагов для списка длиной 1000, а не только 1000 шагов сCounter()
, 10 ^ 12 шагов, где счетчику требуется только 10 ^ 6 для миллиона элементов в списке и т. Д.a.count()
полностью снижает эффективность использования набора.Для подсчета количества появлений:
Чтобы удалить дубликаты:
источник
Counter
может использовать несколько числовых типов, включаяfloat
илиDecimal
не толькоint
.В Python 2.7+ вы можете использовать коллекции. Счетчик для подсчета предметов
источник
Подсчет частоты элементов, вероятно, лучше всего сделать с помощью словаря:
Чтобы удалить дубликаты, используйте набор:
источник
defaultdict
.b = {k:0 for k in a}
?Вот еще одна альтернатива succint,
itertools.groupby
которая также работает для неупорядоченного ввода:полученные результаты
источник
Ты можешь сделать это:
Вывод:
Первый массив - это значения, а второй - количество элементов с этими значениями.
Так что если вы хотите получить массив с числами, вы должны использовать это:
источник
источник
источник
count
смехотворно дорого и неуместно в этом сценарии.Я бы просто использовал scipy.stats.itemfreq следующим образом:
вы можете проверить документацию здесь: http://docs.scipy.org/doc/scipy-0.16.0/reference/generated/scipy.stats.itemfreq.html
источник
По первому вопросу повторите список и используйте словарь, чтобы отслеживать наличие элементов.
Для вашего второго вопроса, просто используйте оператор set.
источник
Этот ответ более явный
источник
...
источник
Я довольно поздно, но это тоже сработает и поможет другим:
будет производить это ..
источник
Вывод
источник
Простое решение с использованием словаря.
источник
max(d.values())
не изменится в последнем цикле. Не вычисляйте это в цикле, вычисляйте это перед циклом.источник
источник
Чтобы удалить дубликаты и сохранить порядок:
источник
Я использую счетчик для генерации частоты. из слов текстового файла в одной строке кода
источник
Это еще один подход, хотя и с использованием более тяжелой, но мощной библиотеки - NLTK.
источник
Еще одно решение с другим алгоритмом без использования коллекций:
источник
Вы можете использовать встроенную функцию, представленную в Python
Приведенный выше код автоматически удаляет дубликаты в списке, а также печатает частоту каждого элемента в исходном списке и список без дубликатов.
Две птицы за один выстрел! XD
источник
Этот подход можно попробовать, если вы не хотите использовать какую-либо библиотеку и делать ее простой и короткой!
о / р
источник
Для записи, функциональный ответ:
Будет чище, если считать нули тоже:
Объяснение:
acc
списка;e
изL
ниже , чем размерacc
, мы просто обновить этот элемент:v+(i==e)
средства ,v+1
если индексi
вacc
это текущий элементe
, в противном случае предыдущее значениеv
;e
изL
больше или равен размеруacc
, мы должны расширитьacc
для размещения нового1
.Элементы не должны быть отсортированы (
itertools.groupby
). Вы получите странные результаты, если у вас есть отрицательные числа.источник
Нашел другой способ сделать это, используя наборы.
источник
источник
Еще один способ - использовать словарь и list.count, ниже наивного способа сделать это.
источник
источник