-2

What I want to implement in Python:

# 1. define int_factory

# 2. get new id of value 123 --> give 0 to 123
a = int_factory[123]
print(a)  # = 0

# 3. get new id of value 12324 --> give 1 to 12324
a = int_factory[12324]
print(a)  # = 1

# 4. Hey, what's 123's id?
a = int_factory[123]
print(a)  # = 0

# 5. get new id of value 513 --> give next id, which is 2 to 513
a = int_factory[513]
print(a)  # = 2

I'd like to implement it using a dictionary data type, or defaultdict in Python.

What I tried:

In [2]: def func():
   ...:     for i in range(10**15):
   ...:         yield i
   ...:

In [3]: a = defaultdict(func)

In [4]: next(a[123])

But this doesn't work.

Is there a more elegant way to implement this in Python?

user3595632
  • 5,380
  • 10
  • 55
  • 111
  • I'm not sure what you are looking for. Is `int_factory` supposed to be a list of generators? Is `a` an integer? Python has a function for random integers in a range: `random.randint`. – Lars Dec 28 '20 at 16:05

3 Answers3

2

I would do it following way:

import collections
import itertools
cnt = itertools.count()
int_factory = collections.defaultdict(cnt.__next__)
print(int_factory[123])
print(int_factory[12324])
print(int_factory[123])
print(int_factory[513])

Output:

0
1
0
2

Explanation: You need to deliver callable when creating collections.default_dict, which will return desired value for missing key

Daweo
  • 31,313
  • 3
  • 12
  • 25
1

You just need to override the __missing__ method, to implement something that uses a counter that you increment

class owndd(defaultdict):
    def __init__(self):
        super().__init__()
        self.counter = 0

    def default_factory(self):
        self.counter += 1
        return self.counter - 1

    def __missing__(self, key):
        self[key] = value = self.default_factory()
        return value

Then use

int_factory = owndd()

a = int_factory[123]
print(a)  # = 0

a = int_factory[12324]
print(a)  # = 1

a = int_factory[123]
print(a)  # = 0

a = int_factory[513]
print(a)  # = 2

for x in 'abcdef':
    print(x, int_factory[x])

0
1
0
2
a 3
b 4
c 5
d 6
e 7
f 8
azro
  • 53,056
  • 7
  • 34
  • 70
0

You can also do it yourself if you wanna keep it simple.

class X:
    def __init__(self):
        self.dict = []
    def __getitem__(self, arg):
        for i in range(len(self.dict)):
            if self.dict[i] == arg:
                return i
        self.dict.append(arg)
        return len(self.dict)-1


int_factory = X()
a = int_factory[123]
print(a)

a = int_factory[12324]
print(a)

a = int_factory[123]
print(a)

a = int_factory[513]
print(a)
mama
  • 2,046
  • 1
  • 7
  • 24