Étant donné un dictionnaire de valeurs de clé de chaîne et d'entiers, quel est le moyen le plus rapide de
au dernier élément du tuple Given:
new_counter = {} for k, v in counter.items(): left = tuple(k[:-1]) right = tuple(k[-1]+'w',) new_k = (left + right,) new_counter[new_k] = v
L'objectif est d'atteindre:
{(tuple(k[:-1])+(k[-1]+'</w>',) ,v) for k,v in counter.items()}
Une façon de le faire est à
J'ai essayé
counter = {('T', 'h', 'e</w>'): 6149, ('P', 'r', 'o', 'j', 'e', 'c', 't</w>'): 205, ('G', 'u', 't', 'e', 'n', 'b', 'e', 'r', 'g</w>'): 78, ('E', 'B', 'o', 'o', 'k</w>'): 5, ('o', 'f</w>'): 39169, ('A', 'd', 'v', 'e', 'n', 't', 'u', 'r', 'e', 's</w>'): 2, ('S', 'h', 'e', 'r', 'l', 'o', 'c', 'k</w>'): 95, ('H', 'o', 'l', 'm', 'e', 's</w>'): 198, ('b', 'y</w>'): 6384, ('S', 'i', 'r</w>'): 30, ('A', 'r', 't', 'h', 'u', 'r</w>'): 18, ('C', 'o', 'n', 'a', 'n</w>'): 3, ('D', 'o', 'y', 'l', 'e</w>'): 2,}
De manière plus détaillée:
counter = {'The': 6149, 'Project': 205, 'Gutenberg': 78, 'EBook': 5, 'of': 39169, 'Adventures': 2, 'Sherlock': 95, 'Holmes': 198, 'by': 6384, 'Sir': 30, 'Arthur': 18, 'Conan': 3, 'Doyle': 2,}
Est y a-t-il une meilleure façon de faire cela?
Concernant l'ajout d'un tuple et le transtypage vers un tuple externe. Pourquoi est-ce autorisé? Le tuple n'est-il pas censé être immuable?
6 Réponses :
Vous êtes sur le point d'apporter quelques modifications à votre code en utilisant tuple
. Vous ne pouvez pas modifier les éléments d'un tuple, mais vous pouvez remplacer un tuple par un autre ::
{tuple(key[:-1])+(key[-1]+'</w>',):value for key,value in counter.items()} {('T', 'h', 'e</w>'): 6149, ('P', 'r', 'o', 'j', 'e', 'c', 't</w>'): 205, ('G', 'u', 't', 'e', 'n', 'b', 'e', 'r', 'g</w>'): 78, ('E', 'B', 'o', 'o', 'k</w>'): 5, ('o', 'f</w>'): 39169, ('A', 'd', 'v', 'e', 'n', 't', 'u', 'r', 'e', 's</w>'): 2, ('S', 'h', 'e', 'r', 'l', 'o', 'c', 'k</w>'): 95, ('H', 'o', 'l', 'm', 'e', 's</w>'): 198, ('b', 'y</w>'): 6384, ('S', 'i', 'r</w>'): 30, ('A', 'r', 't', 'h', 'u', 'r</w>'): 18, ('C', 'o', 'n', 'a', 'n</w>'): 3, ('D', 'o', 'y', 'l', 'e</w>'): 2}
Je choisirais quelque chose comme ceci:
{('A', 'd', 'v', 'e', 'n', 't', 'u', 'r', 'e', 's</w>'): 2, ('A', 'r', 't', 'h', 'u', 'r</w>'): 18, ('C', 'o', 'n', 'a', 'n</w>'): 3, ('D', 'o', 'y', 'l', 'e</w>'): 2, ('E', 'B', 'o', 'o', 'k</w>'): 5, ('G', 'u', 't', 'e', 'n', 'b', 'e', 'r', 'g</w>'): 78, ('H', 'o', 'l', 'm', 'e', 's</w>'): 198, ('P', 'r', 'o', 'j', 'e', 'c', 't</w>'): 205, ('S', 'h', 'e', 'r', 'l', 'o', 'c', 'k</w>'): 95, ('S', 'i', 'r</w>'): 30, ('T', 'h', 'e</w>'): 6149, ('b', 'y</w>'): 6384, ('o', 'f</w>'): 39169}
sortie:
def f(string): l = list(string) l[-1] = l[-1] + '</w>' return tuple(l) dict((f(k), v) for k, v in counter.items())
Je proposerais une version légèrement modifiée de votre solution. À la place d'utiliser constructeur de tuple, vous pouvez utiliser le décompression de tuple:
$ python -m timeit -s "import random" -s "import string" -s "counter = counter = {'The': 6149, 'Project': 205, 'Gutenberg': 78, 'EBook': 5, 'of': 39169, 'Adventures': 2, 'Sherlock': 95, 'Holmes': 198, 'by': 6384, 'Sir': 30, 'Arthur': 18, 'Conan': 3,'Doyle': 2}" "{(*a[:-1],f'a[-1]</w>',):b for a,b in counter.items()}" $ 50000 loops, best of 5: 7.28 usec per loop $ python -m timeit -s "import random" -s "import string" -s "counter = counter = {'The': 6149, 'Project': 205, 'Gutenberg': 78, 'EBook': 5, 'of': 39169, 'Adventures': 2, 'Sherlock': 95, 'Holmes': 198, 'by': 6384, 'Sir': 30, 'Arthur': 18, 'Conan': 3,'Doyle': 2}" "{tuple(key[:-1])+(key[-1]+'</w>',):value for key,value in counter.items()}" $ 20000 loops, best of 5: 11 usec per loop
L'avantage d'utiliser le décompression de tuple est que vous obtiendrez de meilleures performances par rapport au constructeur de tuple
. Je vais vous éclairer davantage à ce sujet en utilisant timeit
. J'utiliserai dict
généré aléatoirement. Chaque clé du dict
aura 2 caractères choisis au hasard parmi les lettres minuscules et chaque valeur sera un entier compris entre 0 et 100. Pour tous ces benchmarks, j'utilise Python 3.7.0
Benchmark avec 100 éléments dans dict
$ python -m timeit -s "import random" -s "import string" -s "counter = {''.join(random.sample(string.ascii_lowercase,2)): random.randint(0,100) for _ in range(1000)}" "{(*a[:-1],f'a[-1]</w>',):b for a,b in counter.items()}" $ 1000 loops, best of 5: 192 usec per loop $ python -m timeit -s "import random" -s "import string" -s "counter = {''.join(random.sample(string.ascii_lowercase,2)): random.randint(0,100) for _ in range(1000)}" "{tuple(key[:-1])+(key[-1]+'</w>',):value for key,value in counter.items()}" $ 1000 loops, best of 5: 321 usec per loop
Benchmark avec 1000 éléments dans dict
$ python -m timeit -s "import random" -s "import string" -s "counter = {''.join(random.sample(string.ascii_lowercase,2)): random.randint(0,100) for _ in range(100)}" "{(*a[:-1],f'a[-1]</w>',):b for a,b in counter.items()} $ 10000 loops, best of 5: 36.6 usec per loop $ python -m timeit -s "import random" -s "import string" -s "counter = {''.join(random.sample(string.ascii_lowercase,2)): random.randint(0,100) for _ in range(100)}" "{tuple(key[:-1])+(key[-1]+'</w>',):value for key,value in counter.items()}" $ 5000 loops, best of 5: 59.7 usec per loop
Benchmark avec dict posté en question
>>> {(*a[:-1],f'a[-1]</w>',):b for a,b in counter.items()}
Ou utilisez str.split
, et faites str.join
et ''
en ajoutant au préalable:
bro-grammer: 0.1293355557653911 Sandeep Kadapa: 0.20885866344797197 U9-Forward: 0.3026948357193003
Avec Python 3, vous pouvez utiliser une expression étoilée dans les tuples.
Vous pouvez essayer:
>>> {(*key[:-1], key[-1] + '</w>'): value for key, value in counter.items()}
Vous pouvez également supprimer .items ()
de votre itération et procéder comme suit:
timeit.timeit(lambda: {tuple(i[:-1]) + (i[-1]+'w',):counter[i] for i in counter}, number=10) 0.000192291005179286
C'est un peu plus rapide.
{tuple(i[:-1]) + (i[-1]+'</w>',):counter[i] for i in counter}
Il semble que votre question appartienne à CodeReview.
Cela est possible car vous créez un NOUVEAU dictionnaire et ses clés sont des tuples DIFFÉRENTS. Les clés d'origine du dictionnaire sont en effet immuables et vous ne les modifiez pas.