web-dev-qa-db-fra.com

Détecter si l'élément est le dernier d'une liste

J'utilise Python 3 et j'essaie de détecter si un élément est le dernier de la liste, mais il y a parfois des répétitions. Ceci est mon code:

a = ['hello', 9, 3.14, 9]
for item in a:
    print(item, end='')
    if item != a[-1]:
        print(', ')

Et je voudrais cette sortie:

hello,
9,
3.14,
9

Mais je reçois cette sortie:

hello, 
93.14, 
9

Je comprends pourquoi je reçois la sortie dont je ne veux pas. Je préférerais que je puisse continuer à utiliser la boucle, mais je peux les contourner. (J'aimerais utiliser ceci avec un code plus compliqué)

5
nedla2004

Plutôt que d'essayer de détecter si vous êtes au dernier élément, imprimez la virgule et le retour à la ligne lors de l'impression du prochain (qui nécessite uniquement de détecter si vous êtes au premier):

a = ['hello', 9, 3.14, 9]
for i, item in enumerate(a):
    if i:  # print a separator if this isn't the first element
        print(',')
    print(item, end='')
print()  # last newline

La fonction enumerate() ajoute un compteur à chaque élément (voir Que signifie énumérer? ), et if i: est vrai pour toutes les valeurs du compteur à l'exception de 0 (le premier élément).

Ou utilisez print() pour insérer des séparateurs:

print(*a, sep=',\n')

La valeur sep est insérée entre chaque argument (*a applique toutes les valeurs de a en tant qu'arguments séparés, voir Que font ** (étoile double) et * (étoile) pour les paramètres? ). Ceci est plus efficace que d'utiliser print(',n'.join(map(str, a))) car il n'est pas nécessaire de créer un tout nouvel objet chaîne.

13
Martijn Pieters

Bien que ces réponses puissent fonctionner pour le cas spécifique du PO, j’ai trouvé qu’elles n’étaient pas satisfaisantes pour une application plus large.

Voici les méthodes que je pourrais penser/vu ici et leurs timings respectifs.

Méthode d'indexation

for x in urlist:
    if urlist.index(x) == len(urlist)-1:
        pass

Méthode de tranche négative

for x in urlist:
    if x == urlist[-1]:
        pass

Méthode Enumerate

for index, x in enumerate(urlist):
    if index == len(urlist)-1:
        pass

Voici un calendrier pour différentes méthodes:

╔════════════════════════════════════════════════════════════════╗
║                       Timing Results (s)                       ║
╠═══════════════════════╦════╦═════════╦════════╦═══════╦════════╣
║ List size             ║ 20 ║ 200     ║ 2000   ║ 20000 ║ 200000 ║
╠═══════════════════════╬════╬═════════╬════════╬═══════╬════════╣
║                       ║ 0  ║ 0.0006  ║ 0.051  ║ 5.2   ║ 560    ║
║ Index Method          ║    ║         ║        ║       ║        ║
╠═══════════════════════╬════╬═════════╬════════╬═══════╬════════╣
║                       ║ 0  ║ 0       ║ 0.0002 ║ 0.003 ║ 0.034  ║
║ Negative Slice Method ║    ║         ║        ║       ║        ║
╠═══════════════════════╬════╬═════════╬════════╬═══════╬════════╣
║ Enumerate Method      ║ 0  ║ 0.00004 ║ 0.0005 ║ 0.016 ║ 0.137  ║
╚═══════════════════════╩════╩═════════╩════════╩═══════╩════════╝

Remarque: les valeurs <10us arrondies à 0

Comme vous pouvez le constater, la méthode d’indexation est toujours plus lente et elle ne fait qu’empirer de façon exponentielle à mesure que la taille de la liste augmente. Je ne vois aucune raison de l'utiliser jamais. La méthode de tranche négative est la plus rapide dans tous les cas, mais si vous avez des éléments en double dans votre liste, cela vous donnera un faux positif . De plus, la méthode de la tranche négative nécessite que la séquence sur laquelle vous effectuez l'itération prenne en charge l'indexation. Ainsi, dans le cas d'éléments en double de votre liste (ou de la séquence ne prenant pas en charge l'index), utilisez la méthode d'énumération la plus rapide, mais pas la plus rapide.


tldr: utilise une tranche négative si tous les éléments sont uniques et si sequence prend en charge l'indexation, sinon la méthode enumerate

7
Matt M.

Si vous souhaitez simplement joindre vos éléments à une chaîne séparée par une virgule + une nouvelle ligne, il est plus facile d'utiliser str.join method:

elements = ['hello', 9, 3.14, 9]
s = ',\n'.join(str(el) for el in elements)
# And you can do whatever you want with `s` string:
print(s)
7
skovorodkin

Vous n'obtenez pas la sortie attendue parce que dans votre code, vous dites: "Hé python, affiche une virgule si l'élément en cours n'est pas égal au dernier élément".

Le deuxième élément 9 est égal au dernier élément, la virgule n'est donc pas imprimée.

La bonne façon de vérifier le dernier élément consiste à vérifier l'index de l'élément:

a = ['hello', 9, 3.14, 9]
for item in a:
    print(item, end='')
    if a.index(item) != len(a)-1: #<--------- Checking for last element here
        print(', ')

(En outre, cela peut générer une erreur de valeur. Vous devriez également vérifier cela.)

4
Shivek Khurana

Si vous cherchez seulement à savoir si l’élément figure en dernier dans la liste (ou n’importe quel élément dans une liste), vous pouvez utiliser une fonction pour vérifier si un élément se trouve en dernier dans une liste.

a = ['hello', 9, 3.14, 9]
def is_last(alist,choice):
        if choice == alist[-1]:
            print("Item is last in list!")
            return True
        else:
            print("Item is not last")
            return False

if is_last(a,9) == True:
    <do things>

else:
    <do other things>
1
Malzyhar