3

I have a list containing 3 fields:

[weight, age, marks]

I would like to apply hash function on each individual row and store these hash values as list. How to proceed with this?

I have combined the individual lists of weight, age, mark using the zip() function:

list1=zip(weight,age,marks)

Kindly help me with this an I am new to python. Thanks in advance.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
user3577226
  • 53
  • 1
  • 5
  • Tell us more. What are values of weight, age, marks, how do you expect the hash to look like. – Jan Vlcinsky Apr 28 '14 at 21:32
  • What are you trying to do? Do you already have a hash function, like `hash(weight, age, marks)`, and want to store the hash value along with each triplet? Or do you want to use some hash-based collection, like `dict`? – jdehesa Apr 28 '14 at 21:33
  • @javidcf , i applied the hash for a single row of list but I am unable to apply it on an entire list of hash values using while loop. – user3577226 Apr 28 '14 at 23:33

3 Answers3

5

You may try to create a hash on tuple structure, like (1, 444, "fine") but not on lists like [1, 444, "fine"] because it is mutable.

In [56]: weight = 120.0

In [57]: age = 99

In [58]: marks = ("a", "b", "cc")

In [59]: row = [weight, age, marks]

Trying hash on mutable structure like list will fail:

In [60]: hash(row)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-60-4a104abdcd18> in <module>()
----> 1 hash(row)

TypeError: unhashable type: 'list'

Tuple is immutable, this will succeed:

In [61]: hash(tuple(row))
Out[61]: 1271481222345795008

Note, that in my example I have created marks as tuple, if you have it as a list, it has to be converted to tuple too:

In [62]: marks = ["a", "b", "cc"]

In [63]: hash((weight, age, marks))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-63-7c8ffc07e716> in <module>()
----> 1 hash((weight, age, marks))

TypeError: unhashable type: 'list'

In [64]: hash((weight, age, tuple(marks)))
Out[64]: 1271481222345795008
Jan Vlcinsky
  • 42,725
  • 12
  • 101
  • 98
0

What about

map(hash, [weight, age, marks])

It gives following list : [ hash(weight), hash(age), hash(marks) ]

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • I applied the hash function on list. Now I am storing these hash values in new list, but the while loop is entering infinite loop. while i in range(len(list1)): listhash[i]= hash(list1[i]) i=i+1 print "Hash finished" – user3577226 Apr 28 '14 at 21:37
  • @user3577226 Why don't you use the more pythonic : _for i in range(len(list1): listhash[i] = hash(list1[1])_ - Also what is the value of len(list(1)) ? – Serge Ballesta Apr 29 '14 at 10:29
  • I sorry. I just realize that weight, age and marks were lists. I thought they were scalar values. – Serge Ballesta Apr 29 '14 at 10:39
0

From your question, I understand that you actually have three lists, weight, age and marks, and have built a "table" with all the records with zip(weight, age, marks).

Now, you want to get the hash of each "row". If you want to use Python built-in hash function, these rows must be immutable; tuples are immutable, lists are not (if you don't know the difference between tuples and lists, look here). That's no problem, because with zip each created "row" is actually a tuple. So, to obtain the hash of each row, you may just use the map function:

hashes = map(hash, list1)

Now you have the hash of each row in hashes (note that you could replace hash with any custom hash function with a tuple argument, if you want). Now you have all the hashes of your rows in hashes, so hashes[23] is the hash of the row list1[23], for example. If you want to have everything in a single structure, just zip it again:

list1_and_hashes = zip(list1, hashes)

Note that each element of list1_and_hashes is a tuple with two elements: first, the row itself (which is in turn a tuple with its corresponding weight, age and marks), and second, the hash of the row. If you want a table where every element has four fields (weight, age, marks and hash), you could use map again with a lambda function.

list1_and_hashes_2 = map(lambda row_hash: list(row_hash[0]) + list(row_hash[1]),
                         list1_and_hashes)

Then you will have in list1_and_hashes_2 the table with four fields in each row.

PD: I'm assuming you are using Python 2. In Python 3, zip and map do not return lists, but generators; in that case, you may need to wrap some of your calls with list(...) to obtain the actual structure.

Community
  • 1
  • 1
jdehesa
  • 58,456
  • 7
  • 77
  • 121