Comparing list with dictionary to make new list in python - python

I have one list and one dictionary. I want to compare the list values with the keys of the dictionary. If I have:
mydict = {'Hello':1,'Hi':2,'Hey':3}
and:
mylist = ['Hey','What\'s up','Hello']
I want the output to be:
output = [3, None, 1]
Thanks!
I tried [mydict[i] for i in mylist] and I get an error instead of None. I then tried using nested for loops (I deleted that bit) but I decided that was to inefficient.

Use a list comprehension:
output = [ mydict.get(key) for key in mylist ]
Note that dict.get returns None if the key is not in the dict.

Use dict.get(), which defaults to None if key does not exist:
[mydict.get(k) for k in mylist]
>>> mydict = {'Hello':1,'Hi':2,'Hey':3}
>>> mylist = ['Hey','What\'s up','Hello']
>>> out = [mydict.get(k) for k in mylist]
>>> out
[3, None, 1]

Related

Mapping Python list based on dict value

I want to map python list based on values of dict. I know how to do that when I have pandas series, but I do not know how to do it with list:
l = ['apple', 'lemmon', 'banana']
x = {'apple':1, 'lemmon':2, 'banana':3, 'chery':4}
l = l.map(x)
print(l)
Desired output:
l = [1,2,3]
This can be solved with Python list comprehensions.
In your case:
l = [x[key] for key in l]
Note that all elements in l need to exist as keys in x.
Using the dict.get method and the map builtin:
m = list(map(x.get, l))
Note that elements of l that are not keys of x will be mapped to None.
With a comprehension:
>>> [x.get(i) for i in l]
[1, 2, 3]

Python - list comprehension , 2D list

I'm trying to figure out how to delete duplicates from 2D list. Let's say for example:
x= [[1,2], [3,2]]
I want the result:
[1, 2, 3]
in this order.
Actually I don't understand why my code doesn't do that :
def removeDuplicates(listNumbers):
finalList=[]
finalList=[number for numbers in listNumbers for number in numbers if number not in finalList]
return finalList
If I should write it in nested for-loop form it'd look same
def removeDuplicates(listNumbers):
finalList=[]
for numbers in listNumbers:
for number in numbers:
if number not in finalList:
finalList.append(number)
return finalList
"Problem" is that this code runs perfectly. Second problem is that order is important. Thanks
finalList is always an empty list on your list-comprehension even though you think it's appending during that to it, which is not the same exact case as the second code (double for loop).
What I would do instead, is use set:
>>> set(i for sub_l in x for i in sub_l)
{1, 2, 3}
EDIT:
Otherway, if order matters and approaching your try:
>>> final_list = []
>>> x_flat = [i for sub_l in x for i in sub_l]
>>> list(filter(lambda x: f.append(x) if x not in final_list else None, x_flat))
[] #useless list thrown away and consumesn memory
>>> f
[1, 2, 3]
Or
>>> list(map(lambda x: final_list.append(x) if x not in final_list else None, x_flat))
[None, None, None, None] #useless list thrown away and consumesn memory
>>> f
[1, 2, 3]
EDIT2:
As mentioned by timgeb, obviously the map & filter will throw away lists that are at the end useless and worse than that, they consume memory. So, I would go with the nested for loop as you did in your last code example, but if you want it with the list comprehension approach than:
>>> x_flat = [i for sub_l in x for i in sub_l]
>>> final_list = []
>>> for number in x_flat:
if number not in final_list:
finalList.append(number)
The expression on the right-hand-side is evalueated first, before assigning the result of this list comprehension to the finalList.
Whereas in your second approach you write to this list all the time between the iterations. That's the difference.
That may be similar to the considerations why the manuals warn about unexpected behaviour when writing to the iterated iterable inside a for loop.
you could use the built-in set()-method to remove duplicates (you have to do flatten() on your list before)
You declare finalList as the empty list first, so
if number not in finalList
will be False all the time.
The right hand side of your comprehension will be evaluated before the assignment takes place.
Iterate over the iterator chain.from_iterable gives you and remove duplicates in the usual way:
>>> from itertools import chain
>>> x=[[1,2],[3,2]]
>>>
>>> seen = set()
>>> result = []
>>> for item in chain.from_iterable(x):
... if item not in seen:
... result.append(item)
... seen.add(item)
...
>>> result
[1, 2, 3]
Further reading: How do you remove duplicates from a list in Python whilst preserving order?
edit:
You don't need the import to flatten the list, you could just use the generator
(item for sublist in x for item in sublist)
instead of chain.from_iterable(x).
There is no way in Python to refer to the current comprehesion. In fact, if you remove the line finalList=[], which does nothing, you would get an error.
You can do it in two steps:
finalList = [number for numbers in listNumbers for number in numbers]
finalList = list(set(finalList))
or if you want a one-liner:
finalList = list(set(number for numbers in listNumbers for number in numbers))

How can I check if a list exist in a dictionary of lists in the same order

Say I have a dictionary of lists,
C = {}
li = []
li.append(x)
C[ind] = li
And I want to check if another list is a member of this dictionary.
for s in C.values():
s.append(w)
Python checks it for any occurrences of the values in s and the dictionary values. But I want to check if any of the lists in the dictionary is identical to the given list.
How can I do it?
Use any for a list of lists:
d = {1 : [1,2,3], 2: [2,1]}
lsts = [[1,2],[2,1]]
print(any(x in d.values() for x in lsts))
True
d = {1:[1,2,3],2:[1,2]}
lsts = [[3,2,1],[2,1]]
print(any(x in d.values() for x in lsts))
False
Or in for a single list:
lst = [1,2]
lst in d.itervalues()
Python will compare each element of both lists so they will have to have the same order to be equal, even if they have the same elements inside the order must also be the same so a simple comparison will do what you want.
in does the trick perfectly, because it does a comparison with each element behind the scenes, so it works even for mutable elements:
lst in d.values()

How to remove a string within a list item in python

On a project I am currently getting returned a list as follows:
[u'40620', u'00700', u'24150', u'11700']
How can I edit the list so it is returned just integer values:
[40620, 00700, 24150, 11700]
Thanks!
Use a list comprehension and int:
>>> lst = [u'40620', u'00700', u'24150', u'11700']
>>> [int(x) for x in lst]
[40620, 700, 24150, 11700]
>>>
Simple one liner:
results = map(int, results)

Adding a item into a a dictionary in Python

I have a dictionary that store the values as lists for each key. For example:
dict1={}
dict1["A"]=[]
I want to append numbers into this list now, but how do I do this correctly? I tried dict1["A"]=dict1["A"].append(1)
this only appended "None". How do I do this?
You just need to call append()
dict1["A"].append(1)
Since the return value of append() itself is None, your version just replaced the old value (a list) with None after you successfully added the item to the list.
A quick demo:
>>> dict1 = {'A': []}
>>> dict1['A'].append(1)
>>> dict1
{'A': [1]}
In Python, in-place operations such as appending to the list, return None:
>>> alist = []
>>> alist.append(1) is None
True
>>> alist
[1]
but as you can see, the list itself was changed.
No need to reassign. Just do dict1["A"].append(1).
The mistake you have done is dict1["A"].append(1) returns None and that you were assigning it back to dict1. Which explains the None you were getting...
That's because append() changes the list in-place and returns None. In your code you assigned that returned Value to dict1["A"]
In [25]: dict1={}
In [26]: dict1["A"]=[]
In [27]: dict1["A"].append(1) #try print dict1["A"].append(1) here
In [28]: dict1
Out[28]: {'A': [1]}

Categories

Resources