0

I'm new to Python coming from a JavaScript background. I'm trying to find a solution for the following. I want to build a dictionary from list data on the fly. I only want to add the list entries that are unique, with a count of 1. Any repeats thereafter I want to keep a count of. Hence from a list containing ["one", "two", "three", "one"] I want to build a dictionary containing {'one': 2, 'two': 1, 'three': 1} I mean to use the list entries as keys and use the dict values for the respective counts. I can't seem to get Python to do it. My code follows. It's currently adding unpredictably to the dictionary totals. I only seem to be able to add the unique entries in the list this way. No luck with any totals. I wanted to ask if I'm on the wrong track or if I'm missing something with this approach. Can someone please help?

import copy

data = ["one", "two", "three", "one"]
new_dict = {}

# build dictionary from list data and only count (not add) any redundant entries
for x in data:

  dict_copy = copy.deepcopy(new_dict)   # loop through a copy (safety)

  for y in dict_copy:

    if x in new_dict:    # check if an entry exists?
      new_dict[y] += 1   # this count gives unpredictable results !!
    else:
      new_dict[x] = 1    # new entry

  else:
    new_dict[x] = 1   # first entry


print(new_dict)
Chuck
  • 192
  • 2
  • 11
  • 2
    search `collections.Counter` and check out some examples – Epsi95 Nov 28 '22 at 05:42
  • 2
    What do you need all those loops and `deepcopy`s for? Just `new_dict = {}`, then `for item in data: new_dict[item] = new_dict.get(item, 0) + 1`. Which is what `Counter` gives you, and since it is already a python builtin, you should just use that – Pranav Hosangadi Nov 28 '22 at 07:23

2 Answers2

0

Use collections.Counter.

In [1]: from collections import Counter

In [2]: items = ["one", "two", "three", "one"]

In [3]: Counter(items)
Out[3]: Counter({'one': 2, 'two': 1, 'three': 1})

In [4]: dict(Counter(items))
Out[4]: {'one': 2, 'two': 1, 'three': 1}

Parag Tyagi
  • 8,780
  • 3
  • 42
  • 47
-1

#1 This might just be the answer I was looking for.

data = ["one", "two", "three", "one"]
new_dict = {}


for x in data:
  if x in new_dict:
    new_dict[x] = new_dict[x] + 1
  else:
    new_dict[x] = 1

print(new_dict)

#2 Using list comprehension.

new_dict = [[x, data.count(x)] for x in set(data)]
Chuck
  • 192
  • 2
  • 11
  • 2
    This is inefficient because `list.count` is O(n), and doing that for all elements of a list makes this approach O(n^2). – Pranav Hosangadi Nov 28 '22 at 06:45
  • 1
    Instead, you could simply loop over all elements of your list _once_, and keep count of them in a dictionary (O(n)), which is _very_ similar to what you'd do in javascript too! – Pranav Hosangadi Nov 28 '22 at 06:46
  • Pranav that's what I was trying to do in my first snippet. I just don't understand why it doesn't work. – Chuck Nov 28 '22 at 07:01