1

Have a bit of a problem distinguishing between identical integers.

In the following (which is obviously a trivial case) a, b, c are integers. I wish to create a dicionary, diction, which will contain {a: 'foo', b: 'bar', c: 'baz'}

diction = {} 
for i in (a, b, c):
    j = ('foo', 'bar', 'baz')[(a, b, c).index(i)]
    diction[i] = j

All runs very nicely until, for example, a and b are the same: the third line will give index 0 for both a and b, resulting in j = 'foo' for each case.

I know lists can be copied by

list_a = [1, 2, 3]
list_b = list(list_a)

or

list_b = list_a[:]

So, is there any way of maybe doing this with my identical integers?

(I tried making one a float, but the value remains the same , so that doesn't work.)

AlG
  • 14,697
  • 4
  • 41
  • 54

5 Answers5

3

To create a dictionary from two different iterables, you can use the following code:

d = dict(zip((a, b, c), ('foo', 'bar', 'baz')))

where zip is used to combine both iterables in a list of tuples that can be passed to the dictionary constructor.

Note that if a==b, then the 'foo' will be overwritten with 'bar', since the values are added to the dictionary in the same order they are in the iterable as if you were using this code:

d[a] = 'foo'
d[b] = 'bar'
d[c] = 'baz'

This is just the standard behaviour of a dictionary, when a new value is assigned to a key that is already known, the value is overwritten.

If you prefer to keep all values in a list, then you can use a collections.defaultdict as follows:

from collections import defaultdict

d = defaultdict(list)
for key, value in zip((a, b, c), ('foo', 'bar', 'baz')):
    d[key].append(value)
DRH
  • 7,868
  • 35
  • 42
jcollado
  • 39,419
  • 8
  • 102
  • 133
2

You can't distinguish between identical objects.

BenH
  • 2,100
  • 2
  • 22
  • 33
1

If a and b have the same value then you can't expect them to point to different positions in dictionary if used as keys. Key values in dictionaries must be unique.

Also if you have two sequences the simplest way to make a dictionary out of them is to zip them together:

tup = (a,b,c)
val = ('foo', 'bar', 'baz')
diction = dict(zip(tup, val))
soulcheck
  • 36,297
  • 6
  • 91
  • 90
1

You can tell them apart if they do not fall between -5 and 256

See also "is" operator behaves unexpectedly with integers

http://docs.python.org/c-api/int.html

The current implementation keeps an array of integer objects for all integers between -5 and 256, when you create an int in that range you actually just get back a reference to the existing object. So it should be possible to change the value of 1. I suspect the behaviour of Python in this case is undefined. :-)

In [30]: a = 257

In [31]: a is 257
Out[31]: False

In [32]: a = 256

In [33]: a is 256
Out[33]: True

You may have to roll your own dictionary like object that implements this sort of behavior though... and it still wouldn't be able to do anything between -5 and 256. I'd need to do more digging to be sure though.

Community
  • 1
  • 1
Derek Litz
  • 10,529
  • 7
  • 43
  • 53
0

All of the answers so far are correct - identical keys can't be re-used in a dictionary. If you absolutely have to try to do something like this, but can't ensure that a, b, and c have distinct values you could try something like this:

d = dict(zip((id(k) for k in (a,b,c)), ('foo', 'bar', 'baz')))

When you go to look up your values though, you'll have to remember to do so like this:

d[id(a)]

That might help, but I am not certain what you're actually after here.

g.d.d.c
  • 46,865
  • 9
  • 101
  • 111