Question Détecter la dernière itération sur dictionary.iteritems () en python


Existe-t-il un moyen simple de détecter la dernière itération en itérant sur un dictionnaire en utilisant iteritems()?


10
2018-05-22 20:02


origine


Réponses:


Ceci est un cas particulier de cette question plus large. Ma suggestion était de créer un générateur d'énumération qui renvoie -1 sur le dernier élément:

def annotate(gen):
    prev_i, prev_val = 0, gen.next()
    for i, val in enumerate(gen, start=1):
        yield prev_i, prev_val
        prev_i, prev_val = i, val
    yield '-1', prev_val

Ajouter gen = iter(gen) si vous voulez qu'il gère des séquences aussi bien que des générateurs.


1
2018-05-22 20:45



Il y a une façon laide de faire ça:

for i, (k, v) in enumerate(your_dict.iteritems()):
    if i == len(your_dict)-1:
        # do special stuff here

Mais vous devriez vraiment envisager si vous en avez besoin. Je suis presque certain qu'il y a un autre moyen.


10
2018-05-22 20:08



it = spam_dict.iteritems()
try:
    eggs1 = it.next()
    while True:
        eggs2 = it.next()
        do_something(eggs1)
        eggs1 = eggs2
except StopIteration:
    do_final(eggs1)

Rapide et assez sale. Est-ce que cela résout votre problème?


2
2018-05-22 20:11



comme d’autres l’ont dit, les dictionnaires n’ont pas d’ordre défini, il est donc difficile d’imaginer pourquoi vous en auriez besoin, mais la voici.

last = None
for current in your_dict.iteritems():
  if last is not None:
    # process last
  last = current

# now last contains the last thing in dict.iteritems()
if last is not None: # this could happen if the dict was empty
  # process the last item

1
2018-05-22 20:18



J'ai récemment eu ce problème, je pensais que c'était la solution la plus élégante car elle vous permettait d'écrire for i,value,isLast in lastEnumerate(...)::

def lastEnumerate(iterator):
    x = list(iterator)
    for i,value in enumerate(x):
        yield i,value,i==len(x)-1

Par exemple:

for i,value,isLast in lastEnumerate(range(5)):
    print(value)
    if not isLast:
        print(',')

1
2018-05-22 20:44



Je le sais si tard, mais voici comment j'ai résolu ce problème:

dictItemCount = len(dict)
dictPosition = 1
for key,value in dict
    if(dictPosition = dictItemCount):
        print 'last item in dictionary'
    dictPosition += 1

1
2018-02-11 21:18



Le dernier élément de la boucle for reste après la boucle for:

for current_item in my_dict:
    do_something(current_item)

try:
    do_last(current_item)
except NameError:
    print "my_dict was empty"

Même si le nom "current_item" est utilisé avant la boucle for, la tentative de bouclage sur un dict vide semble avoir pour effet de supprimer current_item, d'où le NameError


0
2018-05-22 21:46



Vous avez indiqué dans un commentaire ci-dessus que vous en aviez besoin pour construire la clause WHERE d'une instruction SQL SELECT. Cela aidera peut-être:

def make_filter(colname, value):
    if isinstance(value, str):
        if '%' in value:
            return "%s LIKE '%s'" % (colname, value)
        else:
            return "%s = '%s'" % (colname, value)
    return "%s = %s" % (colname, value)

filters = {'USER_ID':'123456', 'CHECK_NUM':23459, 'CHECK_STATUS':'C%'}
whereclause = 'WHERE '+'\nAND '.join(make_filter(*x) for x in filters.iteritems())
print whereclause

qui imprime

WHERE CHECK_NUM = 23459
AND CHECK_STATUS LIKE 'C%'
AND USER_ID = '123456'

0
2018-05-22 22:03



L'approche la plus logique consiste à envelopper la boucle dans un appel qui contient un crochet pour appeler ensuite votre fonctionnalité de post-itération.

Cela pourrait être implémenté en tant que gestionnaire de contexte et appelé via une instruction 'with' ou, pour les versions plus anciennes de Python, vous pourriez utiliser l'ancienne construction 'try:' ... 'finally:'. Il pourrait également être enveloppé dans une classe où l'itération du dictionnaire est auto-répartie (méthode "privée") et le code annexe suit celui de la méthode publique. (Comprendre que la distension entre public vs privé est une question d'intention et de documentation, non imposée par Python).


0
2018-05-22 20:21



Non. Lorsque vous utilisez un itérateur, vous ne savez rien de la position - en fait, l'itérateur peut être infini.

En outre, un dictionnaire est pas ordonné. Donc, si vous en avez besoin, par ex. Pour insérer des virgules entre les éléments, vous devez prendre les éléments, les trier et les parcourir dans la liste des éléments. (key, value) tuples. Et en parcourant cette liste, vous pouvez facilement compter le nombre d'itérations et savoir quand vous avez le dernier élément.


-2
2018-05-22 20:05