0

I have this:

array1 = [[1,2,3],[1,2,3],[2,1,3],[2,1,3],[1,-2,3]]
array2 = [[1,2,3],[1,2,3],[1,2,3],[1,2,3],[0,2,3],[2,1,3]]

and want to create this:

multiArray1 = {[1,2,3]:2, [2,1,3]:2}
multiArray2 = {[1,2,3]:4, [2,1,3]:1}

Question: I am trying to make multiArray1 and multiArray2 as dictionaries containing the same values but the keys give the number of times these values occur in array1 and array2, respectively.

I am not sure what to change in my code. Any help would be greatly appreciated. Thanks.

from collections import defaultdict

array1 = [[1,2,3],[1,2,3],[2,1,3],[2,1,3],[1,-2,3]]
array2 = [[1,2,3],[1,2,3],[1,2,3],[1,2,3],[0,2,3],[2,1,3]]

def f(arrA,arrB):
    multiArray1 = {}
    multiArray2 = {}

    intersect = set(map(tuple,arrA)).intersection(map(tuple,arrB))
    print(set(map(tuple,arrA)).intersection(map(tuple,arrB)))

    for i in intersect:
        multiArray1.update({i:0})
        multiArray2.update({i:0})
    print(multiArray1)
    print(multiArray2)

    multipleArray1 = {}
    multipleArray2 = {}

    for i in intersect:
        for j in range(len(arrA)):
            if str(tuple(arrA[j])) in set(intersect):
                multiArray1[tuple(arrA[j])].append(j)
                print(multiArray1)

                multipleArray1 = defaultdict(list)
                for key, value in multipleArray1:
                    multipleArray1[i].append(j)
                    print(multipleArray1)

    for j in range(len(arrB)):
        if str(tuple(arrB[j])) in set(intersect):
            multiArray2[tuple(arrB[j])].append(j)

            multipleArray2 = defaultdict(list)
            for key, value in multipleArray2:
                multipleArray2[i].append(j)
                print(multipleArray2)

    print(multiArray1)
    print(multiArray2)

f(array1,array2)

The output you get from the above code is this:

{(2, 1, 3), (1, 2, 3)}
{(2, 1, 3): 0, (1, 2, 3): 0}
{(2, 1, 3): 0, (1, 2, 3): 0}
{(2, 1, 3): 0, (1, 2, 3): 0}
{(2, 1, 3): 0, (1, 2, 3): 0}
Mee Seong Im
  • 131
  • 1
  • 8
  • You can't have lists as dictionary keys - they are mutable -> not hashable. – miradulo Jun 05 '16 at 13:51
  • You cannot have `list` as key for a `dictionary`. – Vedang Mehta Jun 05 '16 at 13:51
  • {[1,2,3]:2, [2,1,3]:2} - this is not a valid dict and surly not an array ! – Ohad the Lad Jun 05 '16 at 13:52
  • 2
    I meant array2 and array2 are arrays of an array. Also, I am a beginning python user. I taught myself basic python a little bit a few years ago but that's about what I know about python. – Mee Seong Im Jun 05 '16 at 13:53
  • 1
    Try the collections.Counter class and you will have to ensure, that any list you want to store and measure it's multiplicity on input gets remapped to a tuple, as even the Counter dictionary wrapper needs hashable immutable entries as keys. Please ask on details how to do that with the Counter class I suggested if it is unclear to you and you cannot find out. We are here to help others. – Dilettant Jun 05 '16 at 13:54
  • 1
    According to your code, no they are not. They are lists. – miradulo Jun 05 '16 at 13:54
  • 1
    Welcome then back to Python @MeeSeongIm - as DonkeyKong states there are arrays in Python. What you have here are lists (in square brackets) and they mostly work like arrays, but when learning, it is often beneficial to care for detailed differences in the wording, to minimize misconceptions. Please try my collections.Counter suggestion above and tuple([1, 2, 3]) creates such a hashable tuple (1, 2, 3) from the list [1, 2, 3] further questions along the way highly recommended and HTH – Dilettant Jun 05 '16 at 13:58
  • @Dilettant Thanks for the clarification. If I could upvote your answer, I would! – Mee Seong Im Jun 05 '16 at 14:06
  • You can always come back later thanks for the feedback – Dilettant Jun 05 '16 at 15:02

1 Answers1

0

The trick is, convert them to a string before you make them a key of a dict, because you can not have list as key for a dictionary.

dct1 = {}
dct2 = {}
array1 = [[1,2,3],[1,2,3],[2,1,3],[2,1,3],[1,-2,3]]
array2 = [[1,2,3],[1,2,3],[1,2,3],[1,2,3],[0,2,3],[2,1,3]]

for x in array1:
    cnt = array1.count(x)
    dct1[str(x)] = cnt #here str(x) convert the list to string
for x in array2:
    cnt = array2.count(x)
    dct2[str(x)] = cnt #again here


print (dct1)
print (dct2)

Output

>>> 
{'[1, 2, 3]': 2, '[1, -2, 3]': 1, '[2, 1, 3]': 2}
{'[1, 2, 3]': 4, '[2, 1, 3]': 1, '[0, 2, 3]': 1}
>>> 
GLHF
  • 3,835
  • 10
  • 38
  • 83
  • 2
    Downvoted, this just seems like a bad bad solution to me. It's not a "trick" to convert a list to a string so you can use it as a dictionary key. What if the list is modified? What about dictionary lookup? A better answer would address why the principle of having a list as a dictionary key doesn't make sense. – miradulo Jun 05 '16 at 14:11
  • What if list is modified? Then the key will change. Read the answer carefuly, since we are re-creating the key, not changing. – GLHF Jun 05 '16 at 14:13
  • @GLHF No, it certainly won't. – miradulo Jun 05 '16 at 14:13
  • @GLHF Thanks for the serial downvoting by the way, I was amused :) keep it up. – miradulo Jun 05 '16 at 14:36
  • I'm not downvoting anything, please stop. – GLHF Jun 05 '16 at 14:41
  • @GLHF Sorry, stop what? – miradulo Jun 05 '16 at 14:43