2013-05-04 2 views
1

J'ai une solution de travail pour la création d'une liste certains des nombres aléatoires, compter leurs occurrencies, et le résultat dans un dictionnaire qui donne les éléments suivants:comment accéder à une liste comprehensioned imbriquée

random_ints = [random.randint(0,4) for _ in range(6)] 
dic = {x:random_ints.count(x) for x in set(random_ints)]) 

de telle sorte que pour, disons [0,2,1,2,1,4] j'obtiens {0: 1, 1: 2, 2: 2, 4: 1}

Je me demandais s'il est possible d'exprimer ceci dans un un liner, de préférence sans l'utilisation d'une fonction de bibliothèque - je veux voir ce qui est possible avec python :) Lorsque j'essaie d'intégrer les deux lignes en une seule, je ne sais pas comment exprimer les deux références à la même liste comprimée de random_ints .. ??? Je m'y attendais quelque chose comme:

dic = {x:random_ints.count(x) for x in set([random.randint(0,4) for _ in range(6)] as random_ints)) 

qui bien sûr ne fonctionne pas ...

Je regardais la liste (imbriquée) compréhensions ici sur, mais je ne pouvais pas appliquer les solutions que je trouvais à mon problème.

merci, s.

Répondre

2

Il existe plusieurs façons de réaliser quelque chose comme ça, mais aucune d'elles n'est exactement ce que vous voulez. Ce que vous ne pouvez pas faire est une liaison simple d'un nom à une valeur fixe dans la liste/compréhension de dictée. Si random_ints ne dépend pas de l'une des variables d'itération requises pour dic, il est préférable de le faire comme vous l'avez fait et de créer random_ints séparément. Conceptuellement, les seules choses qui devraient être dans la compréhension des dictées sont les choses qui doivent être créées séparément pour chaque élément dans la dict. random_ints ne répond pas à ce critère; vous n'avez besoin que d'un seul random_ints, donc il n'y a aucune raison de le mettre dans la compréhension des dictées.

Cela dit, une façon de le faire est de faux par itérer sur une liste d'un élément contenant votre random_ints:

{x:random_ints.count(x) for random_ints in [[random.randint(0,4) for _ in range(6)]] for x in set(random_ints)} 
+0

Donc ce faux itération sur la one-element-List (ou 1-uplet comme dans la solution de @Schoolboy) est le moyen d'obtenir la Liste compréhensible nommée pour plus de référence dans la compréhension principale - cool. Mais cela ne devrait pas être fait parce que son concept n'est pas propre - même si je n'ai plus besoin de la liste aléatoire. Je pense que je l'ai eu :) - merci beaucoup! – user1243904

+0

@ user1243904: En général, ce n'est pas Pythonic d'essayer de mettre les choses en une seule ligne juste pour être laconique. Si c'est plus lisible en deux lignes, utilisez deux lignes. – BrenBarn

1

L'utilisation de as dans la liste dict-comprehension ne fonctionnera pas.

Essayez ceci:

dic = {x:random_ints.count(x) 
     for random_ints in ([random.randint(0,4) for _ in range(6)],) 
     for x in set(random_ints)) 

Je pense à l'aide collections.Counter est une meilleure idée:

>>> import collections, random 
>>> c = collections.Counter(random.randint(0, 6) for _ in range(6)) 
>>> c 
Counter({6: 3, 0: 1, 3: 1, 4: 1}) 
+0

grâce, fonctionne parfaitement. – user1243904

2

Voici un one-liner qui repose sur des modules random et collections.

>>> import collections 
>>> import random 
>>> c = collections.Counter(random.randint(0, 6) for _ in range(100)) 
>>> c 
Counter({2: 17, 1: 16, 0: 14, 3: 14, 4: 14, 5: 13, 6: 12}) 
+0

Même si cela utilise un module de bibliothèque, il est qualitativement préférable d'utiliser '.count()' car il n'affiche pas de comportement quadratique. – DSM

Questions connexes