0

I have a set of actions I want to perform randomly. One of the actions iterates over a dictionary . I want every time this action is called, the dictionary iterates to the next position of the dictionary and not to the first one.

If I would need only a value, I could use a list instead of a dictionary, saving the index list outside of the function call, and pass the last index of the list to the function. But I need both values, key and value. I could use 2 lists, storing the key in one, storing the value in the other, save the index outside of the function call, and pass the last index everytime action_two is called, but perhaps there is a shorter way to do it with dictionaries by saving which position the dictionary was iterating somehow and I wouldnt need to use 2 lists?

import random
import time

def action_one(): print "action 1"

def action_two():
    diccionarios_grupos_ids = {
    '580864492030176':'Rafaela Argentina',
    '314744565339924':'Ventas Rafaelinas',
    '976386572414848':'Ventas en Rafaela y Zona',
    '157271887802087':'Rafaela Vende',
    '77937415209':'Mas Poco Vendo',
    '400258686677963':'Clasificados Rafaela',
    '1708071822797472':'Vende Susana Roca Bella Italia Lehmann San Antonio Villa San Jose y Rafaela',
    '639823676133828':'L@s Loc@s de las ofertas sunchales!!!!!!',
    '686381434770519':'H&M Computacion',
    '1489889931229181':'RAFAELA Compra/Venta',
    '228598317265312':'Compra-Venta Rafaela',
    '406571412689579':'Alta Venta'}

    for key,value in diccionarios_grupos_ids.iteritems():
        print key,value
        # I want to iterate in the next position the next time action_two is called
        break

def action_three(): print "action 3"

lista_acciones = [action_one,action_two,action_three]

while True:

    tiempo_random = random.randint(1,3)

    time.sleep(tiempo_random)

    choice = random.choice(lista_acciones)

    choice()
Pablo
  • 3,931
  • 12
  • 47
  • 73
  • An example output would help. It's unclear what you're asking. – ergonaut May 26 '17 at 13:30
  • Do you need the elements of the list later? If not why not just remove them from the list after you reference them and just keep referencing the first element of the list? – Benjamin Commet May 26 '17 at 13:32

2 Answers2

1

Assign iteritem() to a variable, e.g.:

iterable = diccionarios_grupos_ids.iteritems()

for key,value in iterable:
    ...

The problem you will need to solve is using the iterable for multiple calls to action_two() the simplest is a global variable but global variables are generally consider bad style:

def action_two():
    for key,value in iterable:
        print key,value
        break

diccionarios_grupos_ids = {
    '580864492030176':'Rafaela Argentina',
    '314744565339924':'Ventas Rafaelinas',
    '976386572414848':'Ventas en Rafaela y Zona',
    '157271887802087':'Rafaela Vende',
    '77937415209':'Mas Poco Vendo',
    '400258686677963':'Clasificados Rafaela',
    '1708071822797472':'Vende Susana Roca Bella Italia Lehmann San Antonio Villa San Jose y Rafaela',
    '639823676133828':'L@s Loc@s de las ofertas sunchales!!!!!!',
    '686381434770519':'H&M Computacion',
    '1489889931229181':'RAFAELA Compra/Venta',
    '228598317265312':'Compra-Venta Rafaela',
    '406571412689579':'Alta Venta'}

iterable = iter(diccionarios_grupos_ids.items())

But given you just want the next one you can use next():

def action_two():
    print next(iterable)
AChampion
  • 26,341
  • 3
  • 41
  • 64
1

You can use a generator:

def create_grupos_gen():
    diccionarios_grupos_ids = {
    '580864492030176':'Rafaela Argentina',
    '314744565339924':'Ventas Rafaelinas',
    '976386572414848':'Ventas en Rafaela y Zona',
    '157271887802087':'Rafaela Vende',
    '77937415209':'Mas Poco Vendo',
    '400258686677963':'Clasificados Rafaela',
    '1708071822797472':'Vende Susana Roca Bella Italia Lehmann San Antonio Villa San Jose y Rafaela',
    '639823676133828':'L@s Loc@s de las ofertas sunchales!!!!!!',
    '686381434770519':'H&M Computacion',
    '1489889931229181':'RAFAELA Compra/Venta',
    '228598317265312':'Compra-Venta Rafaela',
    '406571412689579':'Alta Venta'}
    for key,value in cycle(diccionarios_grupos_ids.iteritems()):
        yield key, value

grupos_gen = create_grupos_gen()



def action_two():
    key, value = next(grupos_gen)
    print(key,value)

action_two()
action_two()

# 314744565339924 Ventas Rafaelinas
# 1489889931229181 RAFAELA Compra/Venta

Each call to next(grupos_gen) will provide a subsequent key/value pair.

If you want to loop through your dictionary entries, you can use itertools.cycle :

from itertools import cycle

def grupos_gen():
    diccionarios_grupos_ids = {
    '580864492030176':'Rafaela Argentina',
    '314744565339924':'Ventas Rafaelinas',
    '976386572414848':'Ventas en Rafaela y Zona',
    '157271887802087':'Rafaela Vende',
    '77937415209':'Mas Poco Vendo',
    '400258686677963':'Clasificados Rafaela',
    '1708071822797472':'Vende Susana Roca Bella Italia Lehmann San Antonio Villa San Jose y Rafaela',
    '639823676133828':'L@s Loc@s de las ofertas sunchales!!!!!!',
    '686381434770519':'H&M Computacion',
    '1489889931229181':'RAFAELA Compra/Venta',
    '228598317265312':'Compra-Venta Rafaela',
    '406571412689579':'Alta Venta'}
    for key,value in cycle(diccionarios_grupos_ids.iteritems()):
        yield key, value

grupos_iter = grupos_gen()



def action_two():
    key, value = next(grupos_iter)
    print(key,value)


for i in range(15):
    action_two()

# ('400258686677963', 'Clasificados Rafaela')
# ...
# ('228598317265312', 'Compra-Venta Rafaela')
# ('314744565339924', 'Ventas Rafaelinas')
# ('400258686677963', 'Clasificados Rafaela')
# ('639823676133828', 'L@s Loc@s de las ofertas sunchales!!!!!!')
# ('1708071822797472', 'Vende Susana Roca Bella Italia Lehmann San Antonio Villa

For more info, have a look for example at Understanding Generators in Python

Note also that dict are not ordered, so there's no guarantee that your key/values will be iterated over in any reproducible order. If that is important to you, you should use an OrderedDict.

Thierry Lathuille
  • 21,301
  • 10
  • 35
  • 37