10
votes

str.cformat (liste) avec un index négatif ne fonctionne pas dans Python

J'utilise un indice négatif dans les champs de remplacement pour sortir une liste formatée, mais il soulève un typeError.Les codes sont les suivants:

>>> a=[1,2,3]
>>> a[2]
3
>>> a[-1]
3
>>> 'The last:{0[2]}'.format(a)
'The last:3'
>>> 'The last:{0[-1]}'.format(a)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: list indices must be integers, not str


2 commentaires

sonne comme une supervision dans la définition des fonctions de format


Le bogue pertinent de Python's Bugbase - bugs.python.org/issue7951 . En bref, la question est traitée comme un bogue de documentation en raison des effets secondaires de la mise en œuvre de cela et du fait que cela puisse conduire à un mauvais code.


4 Réponses :


14
votes

C'est ce que j'appellerais un problème de conception dans les spécifications de chaîne de format. Par Les docs , xxx pré>

mais, hélas, -1 code> n'est pas "un entier" - c'est une expression. L'opérateur unary-minus n'a même pas particulièrement une priorité, de sorte que, par exemple, impression (-2 ** 2) code> émet un -4 code> - un autre problème courant et sans doute Un gestionnaire de design (l'opérateur ** code> a une priorité plus élevée, de sorte que la hausse-to-puissance se produise en premier, puis le signe de changement demandé par la priorité inférieure unary - code>). p>

quoi que ce soit dans cette position dans la chaîne de format qui n'est pas un entier (mais, par exemple, une expression) est traité comme une chaîne, d'indexer un argument dict - par exemple: P>

$ python3 -c "print('The last:{0[2+2]}'.format({'2+2': 23}))"
The last:23


1 commentaires

Intéressant! Comme pour -2 ** 2 ** 2 Étant égal à -4, je pense que c'est une très bonne chose, car c'est la convention utilisée en mathématiques. Est-ce que quelque chose comme Element_index :: = "Signé_Integer" a un sens?



2
votes

Il y a quelques problèmes ici, une fois que vous avez commencé à creuser:

L'élément en question est appelé "Element_index" qui est défini comme un entier.

problème 1: à moins que les utilisateurs suivent le lien De "Entier" au manuel de référence de la langue, ils ne sauront pas que -1 est considéré comme une expression, pas un entier. À propos, tout le monde tenté de dire "fonctionne comme documenté" devrait voir ProPlem 7 d'abord: -)

Solution préférée: modifier la définition de sorte que "Element_index" puisse avoir une option "-" avant l'entier.

C'est un entier, non? Pas si vite ... plus tard, les documents disent que "une expression de la forme" [index] "fait une recherche d'index utilisant __ getItem __ () "

problème 3: devrait dire '[ollement_index]' (l'index n'est pas défini).

problème 4: tout le monde ne sait pas le haut de leurs têtes ce que __ getItem __ () fait. Besoin de Documents plus clairs.

Nous pouvons donc utiliser un dict ici ainsi qu'un entier, pouvons-nous? Oui, avec un problème ou deux:

L'élément_index est un entier? Oui, cela fonctionne avec un dict: xxx

Il semble que nous puissions également utiliser des chaînes non entières, mais cela nécessite une documentation plus explicite (problème 5): xxx

mais nous ne pouvons pas utiliser de dict avec une clé comme "2" (problème 6): xxx

problème 7: "Entier" devrait vraiment être documenté pour être "décimalinteger" ... 0x22 et 0B11 sont traités comme STR, et 010 (une "octalinteger") est traité comme 10, pas 8: xxx

Mise à jour: PEP 3101 raconte la vraie histoire:
"" "
Les règles d'analyse d'une clé d'article sont très simples. Si cela commence par un chiffre, il est traité comme un nombre, sinon elle est utilisée comme une chaîne.

Parce que les touches ne sont pas délimitées, il n'est pas possible de spécifier des clés de dictionnaires arbitraires (par exemple, les chaînes "10" ou ": -]") à partir d'une chaîne de format.
"" "


0 commentaires

1
votes

correct, cela ne fonctionne pas. Solution:

>>> 'The last:{0}'.format(a[-1])
'The last:3'


1 commentaires

Qui soulève la question suivante: alors pourquoi vous soucier de la conception d'indexation de la séquence restreinte, de la recherche de dict restreint et d'attribuer des installations de recherche dans les chaînes de format, lorsque tout cela peut être fait dans les arguments?



0
votes

Je prends souvent des chaînes de format Python sous forme d'options de configuration - avec la chaîne de format fournie avec une liste spécifique et connue des arguments de mots clés. Par conséquent, aborder les index d'une liste de longueur variable en avant ou en arrière dans la chaîne de format est exactement le genre de chose que je finis à avoir besoin.

Je viens de écrir ce piratage pour faire le travail d'indexation négatif: P>

Hello world


0 commentaires