G. Gare
G. Gare

Reputation: 267

Double loop with dictionary avoiding repetitions

Consider the following code snippet:

foo = {'a': 0, 'b': 1, 'c': 2}

for k1 in foo:
    for k2 in foo:
        print(foo[k1], foo[k2])

The output will be

0 0
0 1
0 2
1 0
1 1 
1 2
2 0
2 1 
2 2

I do not care for the order of the key couples, so I would like a code that outputs

0 0
0 1
0 2
1 1 
1 2
2 2

I tried with

foo = {'a': 0, 'b': 1, 'c': 2}

foo_2 = foo.copy()

for k1 in foo_2:
    for k2 in foo_2:
        print(foo[k1], foo[k2])
    foo_2.pop(k1)

but I clearly got

RuntimeError: dictionary changed size during iteration

Other solutions?

Upvotes: 0

Views: 56

Answers (4)

SACHIN K V
SACHIN K V

Reputation: 11

You can just pass the values of foo dictionary to a list and loop.

foo = {'a': 0, 'b': 1, 'c': 2}
val_list = list(foo.values())

for k1 in foo.values():
  for row in val_list:
    print(k1, row)
  val_list.pop(0)

Upvotes: 0

LD-Link_18
LD-Link_18

Reputation: 36

foo = {'a': 0, 'b': 1, 'c': 2}

foo_2 = foo.copy()

for k1 in foo:
    for k2 in foo_2:
        print(foo[k1], foo[k2])
    foo_2.pop(k1)

You looped in foo_2 two times and when you tried to pop k1 from foo_2 it changed the dictionary while looping causing the error so by first looping foo you avoid the error.

Upvotes: 2

cards
cards

Reputation: 4965

A basic approach.

foo = {'a': 0, 'b': 1, 'c': 2}

for v1 in foo.values():
    for v2 in foo.values():
        if v1 <= v2:
            print(v1, v2)

It could be done with itertools.combinations_with_replacement as well:

from itertools import combinations_with_replacement

foo = {'a': 0, 'b': 1, 'c': 2}

print(*[f'{foo[k1]} {foo[k2]}' for k1, k2 in combinations_with_replacement(foo.keys(), r=2)], sep='\n')

Upvotes: 0

sahasrara62
sahasrara62

Reputation: 11228

>>> foo = {'a': 0, 'b': 1, 'c': 2}
>>> keys = list(foo.keys())
>>> for i, v in enumerate(keys):
...     for j, v2 in enumerate(keys[i:]):
...             print(foo[v], foo[v2])
... 
0 0
0 1
0 2
1 1
1 2
2 2

Upvotes: 0

Related Questions