Grabbing previous iteration in a dict

D

dannywebster

Hello all,

I have a dictionary of which i'm itervalues'ing through, and i'll be
performing some logic on a particular iteration when a condition is
met with trusty .startswith('foo'). I need to grab the previous
iteration if this condition is met. I can do something with an extra
var to hold every iteration while iterating, but this is hacky and not
elegant.

Is there a mechanism whereby I can just index the dict value
subscripts like in an array? I could just rewind by 1 if so.

Cheerz

dan.
 
P

Paul Rubin

I have a dictionary of which i'm itervalues'ing through, and i'll be
performing some logic on a particular iteration when a condition is
met with trusty .startswith('foo'). I need to grab the previous
iteration if this condition is met. I can do something with an extra
var to hold every iteration while iterating, but this is hacky and not
elegant.

You cannot rely on the elements of a dictionary being in any
particular order (dicts are internally hash tables), so the above
is almost certainly ont what you want.
 
D

dannywebster

You cannot rely on the elements of a dictionary being in any
particular order (dicts are internally hash tables), so the above
is almost certainly ont what you want.


Hi - thanks for your reply. How about if I made the dict into a list
(of
which I have done). How would I then reference the previous item?
Can they
be indexed?
 
G

Gary Herron

Hi - thanks for your reply. How about if I made the dict into a list
(of
which I have done). How would I then reference the previous item?
Can they
be indexed?
Yes:

listOfItems = DICT.items()
for i in range(len(listOfItems)):
k,v = listOfItems # Current key,value pair
if whatever:
kPrev,vPrev = listOfItems[i-1] # Previous key,value pair

Still, since there is no proscribed order in which the items are placed
into the list, I wonder how this can be useful. However, this *does*
do what you asked.

Gary Herron
 
H

Hyuga

I have a dictionary of which i'm itervalues'ing through, and i'll be
performing some logic on a particular iteration when a condition is
met with trusty .startswith('foo'). I need to grab the previous
iteration if this condition is met. I can do something with an extra
var to hold every iteration while iterating, but this is hacky and not
elegant.

Why is that so terrible?
previous = None
for key in mydict:
if key.starswith('foo') and previous is not None:
# ...do stuff...
previous = key

Doesn't seem too ugly to me.
Is there a mechanism whereby I can just index the dict value
subscripts like in an array? I could just rewind by 1 if so.

You can't rely on the keys in a dictionary being in any specific
order. But if you want a list of the keys you can just call
mydict.keys() which will give a copy of the dictionary's keys in a
list. Then you can iterate that and use it however you would use any
other list. Note that it's a copy though. It might help if you
better explained exactly what you need to do.
 
Y

Yves Dorfsman

Hi - thanks for your reply. How about if I made the dict into a list
(of
which I have done). How would I then reference the previous item?
Can they
be indexed?

Yes, I ran in a situation similar to yours, I read the content of a file,
and had to both keep the order of the lines in the original file, and create
a dictionary from the lines. So I created a class that contained both a
dictionary and a tuple containing the keys of the dictionary in the original
order. Something like this:

class mydict(object):

def __init__(self, filename):
x = [ e.strip().split() for e in file(filename) ]
self.ordered_lines = tuple([ e[0] for e in x ])
self.dictionary = dict( zip(self.ordered_lines, [ e[1:] for e in x]) )

a = mydict('/some/file')
a.ordered_lines
a.dictionary



Yves.
http://www.SollerS.ca
 
P

Paul Hankin

Hello all,

I have a dictionary of which i'm itervalues'ing through, and i'll be
performing some logic on a particular iteration when a condition is
met with trusty .startswith('foo').  I need to grab the previous
iteration if this condition is met.  I can do something with an extra
var to hold every iteration while iterating, but this is hacky and not
elegant.

Often when you're iterating, 'hacky' code can be lifted out into a
separate generator, keeping the details of the hacks nicely away from
your code. That's true here...

def iterprevious(seq):
"""Generate pairs of (previous element, current element)
from seq."""
last = None
for x in iter(seq):
yield last, x
last = x

Then, when you want use it...

for previous, (key, value) in iterprevious(d.iteritems()):
... In the loop, previous will either be None if we're on the
first element, otherwise (previous_key, previous_value).
 
D

dannywebster

Often when you're iterating, 'hacky' code can be lifted out into a
separate generator, keeping the details of the hacks nicely away from
your code. That's true here...

def iterprevious(seq):
"""Generate pairs of (previous element, current element)
from seq."""
last = None
for x in iter(seq):
yield last, x
last = x

Then, when you want use it...

for previous, (key, value) in iterprevious(d.iteritems()):
... In the loop, previous will either be None if we're on the
first element, otherwise (previous_key, previous_value).


Hi all - some good stuff here. Thanks for the info, I have a few
ideas
to play with.

thanks again

dan.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top