Sont-ils toujours commandés comme dans cet exemple?
Farinha
@Peter. Oui, vous avez trié la liste aux fins de publication. La liste sera-t-elle toujours triée?
S.Lott
2
Non, la liste ne sera pas toujours triée. Ce ne sont pas des devoirs.
Bruce
J'essaie de tracer le graphique de la distribution des degrés d'un réseau.
Bruce
5
@Peter: Veuillez mettre à jour votre question avec les informations utiles. Veuillez ne pas ajouter de commentaires à votre question - vous êtes propriétaire de la question, vous pouvez la corriger pour qu'elle soit complète et claire.
S.Lott
Réponses:
147
Remarque: vous devez trier la liste avant de l'utiliser groupby.
Vous pouvez utiliser à groupbypartir du itertoolspackage si la liste est une liste ordonnée.
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)]
agréable, en utilisant groupby. Je m'interroge sur son efficacité par rapport à l'approche dictée, cependant
Eli Bendersky
32
Le groupe python crée de nouveaux groupes lorsque la valeur qu'il voit change. Dans ce cas, 1,1,1,2,1,1,1] renverrait [3,1,3]. Si vous vous attendiez à [6,1], assurez-vous simplement de trier les données avant d'utiliser groupby.
Evan
4
@CristianCiupitu: sum(1 for _ in group).
Martijn Pieters
6
Ce n'est pas une solution. La sortie ne dit pas ce qui a été compté.
buhtz
8
[(key, len(list(group))) for key, group in groupby(a)]ou {key: len(list(group)) for key, group in groupby(a)}@buhtz
@unutbu: Et si j'ai trois listes, a, b, c pour lesquelles a et b restent les mêmes, mais c change? Comment compter la valeur de c pour laquelle a et c sont identiques?
ThePredator
@Srivatsan: Je ne comprends pas la situation. Veuillez poster une nouvelle question où vous pouvez élaborer.
unutbu
1
Existe-t-il un moyen d'extraire le dictionnaire {1: 4, 2: 4, 3: 2, 5: 2, 4: 1} de l'objet compteur?
Pavan
7
@Pavan: collections.Counterest une sous-classe de dict. Vous pouvez l'utiliser de la même manière qu'un dicton normal. Cependant, si vous voulez vraiment un dict, vous pouvez le convertir en dict dict(counter).
unutbu
1
Fonctionne également en 3.6, supposez donc tout ce qui est supérieur à 2,7
kpierce8
108
Python 2.7+ introduit la compréhension de dictionnaire. Construire le dictionnaire à partir de la liste vous permettra d'obtenir le décompte et de vous débarrasser des doublons.
>>> 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]
Cela fonctionne très bien avec des listes de chaînes par opposition aux entiers comme la question d'origine posée.
Glen Selle
15
C'est plus rapide en utilisant un set:{x:a.count(x) for x in set(a)}
stenci
45
C'est extrêmement inefficace . a.count()effectue une traversée complète pour chaque élément a, ce qui en fait une approche quadradique O (N ^ 2). collections.Counter()est beaucoup plus efficace car il compte en temps linéaire (O (N)). En chiffres, cela signifie que cette approche exécutera 1 million d'étapes pour une liste de longueur 1000, contre seulement 1000 étapes avec Counter(), 10 ^ 12 étapes où seulement 10 ^ 6 sont nécessaires par Counter pour un million d'éléments dans une liste, etc.
Martijn Pieters
3
@stenci: bien sûr, mais l'horreur d'utiliser a.count()complètement éclipse l'efficacité d'avoir utilisé un ensemble là-bas.
Martijn Pieters
2
@MartijnPieters une raison de plus de l'utiliser moins de fois :)
stenci
48
Pour compter le nombre d'apparitions:
from collections import defaultdict
appearances = defaultdict(int)for curr in a:
appearances[curr]+=1
@phkahler: Le mien ne serait qu'un tout petit peu mieux que ça. Cela ne vaut pas la peine que je poste une réponse distincte lorsque cela peut être amélioré avec un petit changement. Le but de SO est d'arriver aux meilleures réponses. Je pourrais simplement modifier cela, mais je préfère laisser à l'auteur d'origine la possibilité d'apporter ses propres améliorations.
S.Lott
1
@ S.Lott Le code est beaucoup plus propre sans avoir à importer defaultdict.
bstrauch24
Pourquoi ne pas preinitialize b: b = {k:0 for k in a}?
DylanYoung, le
20
Voici une autre alternative succint utilisant itertools.groupbyqui fonctionne également pour une entrée non ordonnée:
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))}
Bien que cet extrait de code puisse être la solution, y compris une explication aide vraiment à améliorer la qualité de votre message. N'oubliez pas que vous répondrez à la question des lecteurs à l'avenir, et que ces personnes ne connaissent peut-être pas les raisons de votre suggestion de code
Rahul Gupta
Oui le fera Rahul Gupta
Anirban Lahiri
7
seta = set(a)
b =[a.count(el)for el in seta]
a = list(seta)#Only if you really want it.
l'utilisation de listes countest ridiculement coûteuse et inutile dans ce scénario.
Idan K
@IdanK pourquoi compter coûte cher?
Kritika Rajain
@KritikaRajain Pour chaque élément unique de la liste, vous parcourez la liste entière pour générer un décompte (quadratique en nombre d'éléments uniques dans la liste). Au lieu de cela, vous pouvez parcourir la liste une fois et compter le nombre de chaque élément unique (linéaire dans la taille de la liste). Si votre liste ne contient qu'un seul élément unique, le résultat sera le même. De plus, cette approche nécessite un ensemble intermédiaire supplémentaire.
DylanYoung
7
J'utiliserais simplement scipy.stats.itemfreq de la manière suivante:
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)
La collection d'ensemble ne permet pas les doublons, passer une liste au constructeur set () donnera un itérable d'objets totalement uniques. La fonction count () renvoie un nombre entier lorsqu'un objet qui se trouve dans une liste est passé. Avec cela, les objets uniques sont comptés et chaque valeur de comptage est stockée en l'ajoutant à une sortie de liste vide
Le constructeur list () est utilisé pour convertir l'ensemble (a) en liste et référencé par la même variable 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())ne changera pas dans la dernière boucle. Ne le calculez pas dans la boucle, calculez-le avant la boucle.
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)
Veuillez ne pas publier de réponses uniquement en code, mais clarifiez votre code, surtout lorsqu'une question a déjà une réponse valide.
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]
j'utilise Counter pour générer une fréquence. dicter des mots d'un fichier texte sur 1 ligne de code
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])
Encore une autre solution avec un autre algorithme sans utiliser de collections:
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
Vous pouvez utiliser la fonction intégrée fournie en python
l.count(l[i])
d=[]for i in range(len(l)):if l[i]notin d:
d.append(l[i])print(l.count(l[i])
Le code ci-dessus supprime automatiquement les doublons dans une liste et imprime également la fréquence de chaque élément dans la liste d'origine et la liste sans doublons.
>>> 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]
C'est plus propre si vous comptez aussi les zéros:
>>> 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]
Une explication:
nous commençons avec une accliste vide ;
si l'élément suivant ede Lest inférieur à la taille de acc, nous mettons simplement à jour cet élément: v+(i==e)signifie v+1si l'index ide accest l'élément courant e, sinon la valeur précédente v;
si l'élément suivant ede Lest supérieur ou égal à la taille de acc, nous devons développer accpour héberger le nouveau 1.
Les éléments n'ont pas besoin d'être triés ( itertools.groupby). Vous obtiendrez des résultats étranges si vous avez des nombres négatifs.
J'ai trouvé une autre façon de procéder en utilisant des ensembles.
#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)
Pour rechercher des éléments uniques dans la liste
a =[1,1,1,1,2,2,2,2,3,3,4,5,5]
a = list(set(a))
Pour trouver le nombre d'éléments uniques dans un tableau trié à l'aide du dictionnaire
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)
Une autre façon consiste à utiliser un dictionnaire et le list.count, ci-dessous une manière naïve de le faire.
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)
Réponses:
Remarque: vous devez trier la liste avant de l'utiliser
groupby
.Vous pouvez utiliser à
groupby
partir duitertools
package si la liste est une liste ordonnée.Production:
la source
groupby
. Je m'interroge sur son efficacité par rapport à l'approche dictée, cependantsum(1 for _ in group)
.[(key, len(list(group))) for key, group in groupby(a)]
ou{key: len(list(group)) for key, group in groupby(a)}
@buhtzDans Python 2.7 (ou plus récent), vous pouvez utiliser
collections.Counter
:Si vous utilisez Python 2.6 ou une version antérieure, vous pouvez le télécharger ici .
la source
collections.Counter
est une sous-classe dedict
. Vous pouvez l'utiliser de la même manière qu'un dicton normal. Cependant, si vous voulez vraiment un dict, vous pouvez le convertir en dictdict(counter)
.Python 2.7+ introduit la compréhension de dictionnaire. Construire le dictionnaire à partir de la liste vous permettra d'obtenir le décompte et de vous débarrasser des doublons.
la source
{x:a.count(x) for x in set(a)}
a.count()
effectue une traversée complète pour chaque élémenta
, ce qui en fait une approche quadradique O (N ^ 2).collections.Counter()
est beaucoup plus efficace car il compte en temps linéaire (O (N)). En chiffres, cela signifie que cette approche exécutera 1 million d'étapes pour une liste de longueur 1000, contre seulement 1000 étapes avecCounter()
, 10 ^ 12 étapes où seulement 10 ^ 6 sont nécessaires par Counter pour un million d'éléments dans une liste, etc.a.count()
complètement éclipse l'efficacité d'avoir utilisé un ensemble là-bas.Pour compter le nombre d'apparitions:
Pour supprimer les doublons:
la source
Counter
peut en fait utiliser plusieurs types numériques, y comprisfloat
ouDecimal
pas seulementint
.Dans Python 2.7+, vous pouvez utiliser des collections. Compteur pour compter les éléments
la source
Il est probablement préférable de compter la fréquence des éléments avec un dictionnaire:
Pour supprimer les doublons, utilisez un ensemble:
la source
defaultdict
.b = {k:0 for k in a}
?Voici une autre alternative succint utilisant
itertools.groupby
qui fonctionne également pour une entrée non ordonnée:résultats
la source
Tu peux le faire:
Production:
Le premier tableau est des valeurs et le second tableau est le nombre d'éléments avec ces valeurs.
Donc, si vous voulez obtenir simplement un tableau avec les nombres, vous devez utiliser ceci:
la source
la source
la source
count
est ridiculement coûteuse et inutile dans ce scénario.J'utiliserais simplement scipy.stats.itemfreq de la manière suivante:
vous pouvez consulter la documentation ici: http://docs.scipy.org/doc/scipy-0.16.0/reference/generated/scipy.stats.itemfreq.html
la source
Pour votre première question, parcourez la liste et utilisez un dictionnaire pour garder une trace de l'existence des éléments.
Pour votre deuxième question, utilisez simplement l'opérateur set.
la source
Cette réponse est plus explicite
la source
...
la source
Je suis assez en retard, mais cela fonctionnera aussi et aidera les autres:
va produire cela ..
la source
Production
la source
Solution simple à l'aide d'un dictionnaire.
la source
max(d.values())
ne changera pas dans la dernière boucle. Ne le calculez pas dans la boucle, calculez-le avant la boucle.la source
la source
Pour supprimer les doublons et maintenir l'ordre:
la source
j'utilise Counter pour générer une fréquence. dicter des mots d'un fichier texte sur 1 ligne de code
la source
Une autre approche pour ce faire, bien qu'en utilisant une bibliothèque plus lourde mais puissante - NLTK.
la source
Encore une autre solution avec un autre algorithme sans utiliser de collections:
la source
Vous pouvez utiliser la fonction intégrée fournie en python
Le code ci-dessus supprime automatiquement les doublons dans une liste et imprime également la fréquence de chaque élément dans la liste d'origine et la liste sans doublons.
Deux oiseaux pour un coup! XD
la source
Cette approche peut être essayée si vous ne voulez utiliser aucune bibliothèque et la garder simple et courte!
o / p
la source
Pour mémoire, une réponse fonctionnelle:
C'est plus propre si vous comptez aussi les zéros:
Une explication:
acc
liste vide ;e
deL
est inférieur à la taille deacc
, nous mettons simplement à jour cet élément:v+(i==e)
signifiev+1
si l'indexi
deacc
est l'élément courante
, sinon la valeur précédentev
;e
deL
est supérieur ou égal à la taille deacc
, nous devons développeracc
pour héberger le nouveau1
.Les éléments n'ont pas besoin d'être triés (
itertools.groupby
). Vous obtiendrez des résultats étranges si vous avez des nombres négatifs.la source
J'ai trouvé une autre façon de procéder en utilisant des ensembles.
la source
la source
Une autre façon consiste à utiliser un dictionnaire et le list.count, ci-dessous une manière naïve de le faire.
la source
la source