Reputation: 2853
I am attempting to write the corresponding list comprehension for the following code snippet.
# Initialize data.
queryRelDict = {'1': [1, 2, 3],
'2': [4, 5, 6],
'3': [11, 13, 14]}
related_docs_indices = [1, 2, 3, 4, 5, 6, 7, 8, 12, 13, 14]
relOrNot = [0] * k
for item in queryRelDict.keys():
for i in range(len(related_docs_indices)):
if related_docs_indices[i] + 1 in queryRelDict[item]:
relOrNot[i] = 1
Basically I have a dictionary, where each key has a list as its value. Now my list relOrNot[i]
needs to be 1, if ith
element of related_docs_indices
is in either of the lists in the dictionary.
The desired Output is:
[1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1]
I tried the following two variations, but is not able to get the desired output.
relOrNot2 = [1 for item in queryRelDict.keys() for i in range(len(related_docs_indices)) if related_docs_indices[i] + 1 in queryRelDict[item]]
but the output is
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
I also tried
relOrNot2 = [1 if related_docs_indices[i] + 1 in queryRelDict[item] else 0 for item in queryRelDict.keys() for i in range(len(related_docs_indices))]
Corresponding Output:
[0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]
What modification is necessary to get the desired output?
Upvotes: 0
Views: 163
Reputation: 286
Here if you want an one-liner :)
relOrNot = [1 if v in set().union(*queryRelDict.values()) else 0 for v in related_docs_indices]
Upvotes: 1
Reputation: 3477
Create a set with all keys and all values and in your loop just look if the required value is in the set.
s = set()
for (k,v) in queryRelDict.items():
s.add(int(k))# because your keys are string
s = s | set(v)
map(lambda x:1 if x in s else 0, related_docs_indices)
=>[1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1]
Upvotes: 1
Reputation: 109666
For each key, you are iterating through the related_doc_indices
and checking if there is a matching value within the set of values for that key. For key '1', it would look like this:
key 1 values = [1, 2, 3]
related_docs_indices = [
1, # 1 (match)
2, # 1 (match)
3, # 1 (match)
4, # 0 (no match)
5, # 0 (no match)
6, # 0 (no match)
7, # 0 (no match)
8, # 0 (no match)
12, # 0 (no match)
13, # 0 (no match)
14] # 0 (no match)
The desired output for this key should thus be:
[1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]
One issue that you have is that keys are unordered in dictionaries, so that results of the longer list can vary depending on the random order of the keys. For example:
>>> queryRelDict.keys()
['1', '3', '2']
Let's say you first sort the keys, then I believe the desired output should look like this:
[1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, # key '1'
0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, # key '2'
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1] # key '3'
keys = queryRelDict.keys()
keys.sort()
>>> [1 if i in queryRelDict.get(item) else 0
for item in keys for i in related_docs_indices]
#[1, 2, 3, 4, 5, 6, 7, 8, 12, 13, 14] related_doc_indices
[1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, # key '1' values: [1, 2, 3]
0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, # key '2' values: [4, 5, 6]
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1] # key '3' values: [11, 13, 14] (note 11 is not in related_doc_indices)
Upvotes: 1
Reputation: 15433
If your desired output is a list relOrNot
, where relOrNot[i]
is 1, if ith element of related_docs_indices
is in either of the lists in the dictionary queryRelDict
(then it must have the same length as related_docs_indices
), then you can do the following:
# first create one flat list with all elements of the sublists in the dictionary
flatlist = [i for sublist in queryRelDict.itervalues() for i in sublist]
relOrNot = [1 if i in flatlist else 0 for i in related_docs_indices]
# [1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1]
Upvotes: 1