views:

100

answers:

6

Here's my problem:

Lets say I have two dictionaries, dict_a and dict_b.

Each of them have similar keys and values that I can manipulate in the same way, and in fact that's what I'm doing in a large piece of code. Only I don't want to have to write it twice. However, I can't do something like this:

if choose_a == 1:
    for x and y in dict_a.iteritems():
    # goto line 20

if choose_b == 1:
    for x and y in dict_b.iteritems():
    # goto line 20

 # line 20
 # do stuff with x and y.

Except I have no idea what to do in a situation like this. If there is a like thread, please point me to it, and forgive me if I have violated anything (first post). Thanks in advance, I appreciate any help.

A: 

Just define a fuction.

def do_stuff(x, y):
    # Do stuff
    pass

if choose_a == 1:
    for x and y in dict_a.iteritems():
    do_stuff(x, y)

if choose_b == 1:
    for x and y in dict_b.iteritems():
    do_stuff(x, y)
Joe Kington
Would the downvoter care to explain what's wrong with this answer?
Adam Bernier
I would like to know too. I *up*voted this, since it's not a bad answer, although I prefer ~unutbu's solution.
catchmeifyoutry
+3  A: 

Perhaps do something like this:

if choose_a == 1: the_dict=dict_a
elif choose_b == 1: the_dict=dict_b

for x,y in the_dict.iteritems():
    # do stuff with x and y.
unutbu
was writing the same thing
RC
+1, this has a single moment of choice after which your code is agnostic where the dict came from. Adding a dict_c or dict_d later is trivial, and has minimal code duplication.
catchmeifyoutry
This is the kind of idea I was looking for, thank you!
Alison
+3  A: 
def do_stuff( d ):
  for x and y in d.iteritems():
    whatever with x and y
if choose_a == 1: do_stuff( dict_a )    
if choose_b == 1: do_stuff( dict_b )
eruciform
A: 

How about this:

d = dict_a if choose_a else dict_b
for x, y in d.items():
    # do stuff with x and y

Obviously that assumes that you're going to use one or the other; pretty simple to add an if statement if that's not the case though. Also, your x and y syntax is invalid, but I guess you'll figure that out :)

Peter
+1  A: 

What do you want to happen if both choose_a and choose_b are true? What if neither of them is true? Is either of these conditions at all possible...?

Can you afford to move all the "stuff" to a separate function as a couple of answers have suggested, or would the resulting scope change be a problem?

As you see, you've left many things underspecified (or totally unspecified). Assuming the worst...:

  1. both the choose_... variables could be true, in which case you need to use both dicts
  2. both the choose_... variables could be false, in which case you want to do nothing
  3. you need the "stuff" to happen within the current function due to scoping issues,

then...:

thedicts = []
if choose_a == 1: thedicts.append(dict_a)
if choose_b == 1: thedicts.append(dict_b)

for d in thedicts:
    for x, y in d.iteritems():
        ...do stuff _locally_ with x and y...

You could express the building of the thedicts list more concisely, but, I think, not as clearly, by rolling it up in the for statement, e.g. as follows...:

for d in [d for d, c in zip((dict_a, dict_b), (choose_a, choose_b)) if c]:
Alex Martelli
A: 

You can put the two dictionaries in a dict and then select them with a key

for example:

choice = 'A'  # or choice = 'B'
working_dict = {'A': dict_a, 'B': dict_b}[choice]
for x,y in working_dict.iteritems():
    # do stuff with x and y

This is slightly different from your approach using two flags. If you are stuck with that scheme you could use something like this to set the value of choice

if choose_a == 1:
    choice = 'A'
elif choose_b == 1:
    choice = 'B'
else: 
    pass # maybe this should raise an exception?

Perhaps it is just easier to write it this way:

if choose_a == 1:
    working_dict = dict_a
elif choose_b == 1:
    working_dict = dict_b
else: 
    pass # maybe this should raise an exception?

for x,y in working_dict.iteritems():
    # do stuff with x and y
gnibbler