beta
beta

Reputation: 5686

conditional check inside list comprehension with dictionary

I have a list of lists looking like:

l = [['A', 1], ['B', 10],['C', 100]]

Then I have a dict where the keys correspond to the first item of the above list of lists. The values are lists (in my example below there is only one value per list, but actually I have more there. But for the sake of brevity, I only show one value):

d = {'A': [2], 'B': [5], 'C': [110] }

I now want to create a new list based on the following logic: for every first list of lists item of the first list (e.g. A, B, and C), I want to look, if the corresponding value in the dictionary is smaller. If the value in the dictionary is smaller, then use this value in the result list. If the value is not smaller, then use the same value.

The output, hence, should look as follows:

[['A', 1], ['B', 5],['C', 100]]

I tried the following list comprehension, but I get an error:

[[i[0], d[i][0] if d[i][0] < i[1] else i[0],i[1]] for i in l])

I get this error:

TypeError: unhashable type: 'list'

EDIT:

After doing some research, I see that people say that the problem is, that I use a list as the key in my dict. It is definitely not my intention to do this. In the example data I have shown above, you see that my intention is to use strings as keys in my dictionary. I just checked all my keys with d.keys() and there are only strings in my keys. So this seems not to be the problem.

Upvotes: 0

Views: 419

Answers (3)

Mohideen bin Mohammed
Mohideen bin Mohammed

Reputation: 20137

you can try this,

>>> d = {'A': [2], 'B': [5], 'C': [110] }
>>> l = [['A', 1], ['B', 10],['C', 100]]
>>> [i if i[1] < d[i[0]][0] else [i[0],d[i[0]][0]] for i in l]
[['A', 1], ['B', 5], ['C', 100]]
>>> 

now will move onto your error, Unhashable type list ,

you try to pass entire list as a dic key instead of string.. your error in ,

if d[i][0] change it into if d[i[0]] < i[1]

so it will be like this,

>>> [[i[0], d[i][0] if d[i[0]] < i[1] else i[0],i[1]] for i in l]
[['A', 'A', 1], ['B', 'B', 10], ['C', 'C', 100]]
>>> 

Upvotes: 2

crazyGamer
crazyGamer

Reputation: 1139

You can do this, using the in-built min function and using list comprehension.

[This finds the minimum of the set of values in dictionary as well as the original list]:

[[x[0], min(min(d[x[0]]), x[1])] for x in ls]

Also, a simple solution using for loop:

for i in range(len(ls)):
    ls[i][1] = min(min(d[ls[i][0]]), ls[i][1])

To do the same, where the minimum is calculated only between original list value and first value of dictionary's list, do:

[[x[0], min(d[x[0]][0], x[1])] for x in ls]

Upvotes: 0

RomanPerekhrest
RomanPerekhrest

Reputation: 92854

Simple list comprehension:

l = [['A', 1], ['B', 10],['C', 100]]
d = {'A': [2], 'B': [5], 'C': [110] }
result = [[subl[0], d[subl[0]][0]] if d[subl[0]][0] < subl[1] else subl for subl in l]

print(result)

The output:

[['A', 1], ['B', 5], ['C', 100]]

Upvotes: 0

Related Questions