1

I want to use counter function to count for the occurrences of the value 0 for each array inside a list.

from collections import Counter
[Counter(x) for x in a]
[Counter(x)[0] for x in a]

Using the above code it only applies to example like:

a = [array([-2, 0, 0]), array([-2, -1, 1])]

When it applies to the code below which have multiple arrays it raises a TypeError:

a = [[array([-2, 0, 0]), array([-2, -1, 1])], [array([3, -1]), array([1, -2])]]

Expected output:

[[2, 0], [0, 0]]

Can anyone help me?

5
  • 1
    What does array() do? Commented Jun 8, 2015 at 6:33
  • "it returns error": what is that error? Please post the full traceback. Commented Jun 8, 2015 at 6:36
  • If I ignore array, the logic would be simple: [Counter(x)[0] for x in list(chain(*a))] Commented Jun 8, 2015 at 6:36
  • @AbhiP That will give a flat list though. Commented Jun 8, 2015 at 6:39
  • Traceback (most recent call last): File "<pyshell#2>", line 1, in <module> [Counter(d) for d in x] File "C:\Python27\lib\collections.py", line 450, in init self.update(iterable, **kwds) File "C:\Python27\lib\collections.py", line 532, in update self[elem] = self_get(elem, 0) + 1 TypeError: unhashable type: 'numpy.ndarray' Commented Jun 8, 2015 at 6:39

1 Answer 1

4

Counter cannot magically descend your list and only count the elements in each array independently. It will always act upon the direct iterable you pass to it. In your first example, you iterate your list and then use each element to create a new Counter; since you have a flat list of array objects, you keep passing array objects to the call. In your second example however, you have a list of lists (which then contain array objects). So when you do the same thing as before, you try to create a counter from those lists. So what the counter tries to do is count how often a certain array object appears in that list. But as array objects are not hashable, it cannot identify them and you get that error. But that’s not the logic you want to use anyway.

Instead, you want to walk through all your lists and whenever you encounter an array, create a counter from it:

def convert (obj):
    if isinstance(obj, list):
        return list(map(convert, obj))
    else:
        return Counter(obj)[0]
>>> a = [[array([-2, 0, 0]), array([-2, -1, 1])], [array([3, -1]), array([1, -2])]]
>>> convert(a)
[[2, 0], [0, 0]]
>>> b = [array([-2, 0, 0]), array([-2, -1, 1])]
>>> convert(b)
[2, 0]
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.