Skip to main content
Updated info, talked about complexity
Source Link
Peilonrayz
  • 43.5k
  • 7
  • 76
  • 155

You can use a default dictdefaultdict, to remove the if v else. To achiveachieve this, you can do:

from collections import defaultdict
counted = defaultdict(int)
for i,v in enumerate(x):
    counted[v] += 1

To remove the need for out and enumerate you can yield on each iteration.
This would make your code very small and readable.

from collections import defaultdict

def times_so_far(list_):
    counted = defaultdict(int)
    for v in list_:
        counted[v] += 1
        yield counted[v]

print(list(times_so_far([1,1,2,3,1,3])))
#[0, 1, 0, 0, 2, 1]

It will return a generator objectgenerator object, hence why I use list. If this is a problem then you can change yield to out.append() and re-add out.

This has \$O(n)\$ runtime, with a min \$O(n)\$ and maximum \$O(2n)\$ memory usage.

You can use a default dict, to remove the if v else. To achive this, you can do:

from collections import defaultdict
counted = defaultdict(int)
for i,v in enumerate(x):
    counted[v] += 1

To remove the need for out and enumerate you can yield on each iteration.
This would make your code very small and readable.

from collections import defaultdict

def times_so_far(list_):
    counted = defaultdict(int)
    for v in list_:
        counted[v] += 1
        yield counted[v]

print(list(times_so_far([1,1,2,3,1,3])))
#[0, 1, 0, 0, 2, 1]

It will return a generator object, hence why I use list. If this is a problem then you can change yield to out.append() and re-add out.

You can use a defaultdict, to remove the if v else. To achieve this, you can do:

from collections import defaultdict
counted = defaultdict(int)
for i,v in enumerate(x):
    counted[v] += 1

To remove the need for out and enumerate you can yield on each iteration.
This would make your code very small and readable.

from collections import defaultdict

def times_so_far(list_):
    counted = defaultdict(int)
    for v in list_:
        counted[v] += 1
        yield counted[v]

print(list(times_so_far([1,1,2,3,1,3])))
#[0, 1, 0, 0, 2, 1]

It will return a generator object, hence why I use list. If this is a problem then you can change yield to out.append() and re-add out.

This has \$O(n)\$ runtime, with a min \$O(n)\$ and maximum \$O(2n)\$ memory usage.

Source Link
Peilonrayz
  • 43.5k
  • 7
  • 76
  • 155

You can use a default dict, to remove the if v else. To achive this, you can do:

from collections import defaultdict
counted = defaultdict(int)
for i,v in enumerate(x):
    counted[v] += 1

To remove the need for out and enumerate you can yield on each iteration.
This would make your code very small and readable.

from collections import defaultdict

def times_so_far(list_):
    counted = defaultdict(int)
    for v in list_:
        counted[v] += 1
        yield counted[v]

print(list(times_so_far([1,1,2,3,1,3])))
#[0, 1, 0, 0, 2, 1]

It will return a generator object, hence why I use list. If this is a problem then you can change yield to out.append() and re-add out.