Remove elements from list - python

I have a variable:
x = 4
And I have a list:
list = [{'name': u'A', 'value': '1'}, {'name': u'B', 'value': '4'}, {'name': u'C', 'value': '2'}]
How can I exclude/remove the element in list where value=x?

A list comprehension is perfect for this.
[ k for k in list if int(k['value']) != x ]
You can also use filter, but I believe list comprehensions are preferred in terms of style:
filter(lambda p: int(p['value']) != x, list)
edit: noticed your values are strings, so I added an int conversion.

Related

python: search in list of lists of dictionaries

I want to iterate over a list of lists of dictionaries:
data = [
{'name': 'sravan'},
{'name': 'bobby'},
{'name': 'ojsawi', 'number': '123'},
{'name': 'rohith', 'number': '456'},
{'name': 'gnanesh', 'number': '123'}
]
Furthermore I want to check each entry if there is a key number where the value is 123.
If so, I want to append the value of name of this entry in a new list
which would be 'ojsawi' and 'gnanesh' in the above case.
Else, I want to append 0 in the new list.
This means, the final new_list with the appended values should look like this:
new_list = {0, 0, 'ojsawi', 0, 'gnanesh'}
I have tried different versions/possibillities with 2D for loops and lambdas etc. but I think the main problem is that the lists have different sizes. Any help/tipps would be much appreciated.
You can define it with list comprehensions with a nested if/else in it:
new_list = [x.get('name') if x.get('number') == '123' else 0 for x in data]
Outputting:
[0, 0, 'ojsawi', 0, 'gnanesh']
Other than list comprehensions, you can also do it using map() and functional programming if you want. Note that map() returns an iterator which generates things as you go if you are using a for loop, so if you want the entire result immediately, use list() around your map() function.
def zerofilter(my_dict):
number = my_dict.get("number")
if number != "123":
return 0
else:
return my_dict.get("name")
data = [
{'name': 'sravan'},
{'name': 'bobby'},
{'name': 'ojsawi', 'number': '123'},
{'name': 'rohith', 'number': '456'},
{'name': 'gnanesh', 'number': '123'}
]
print(list(map(zerofilter, data))) # output is [0, 0, 'ojsawi', 0, 'gnanesh']
# You can also do this:
for res in map(zerofilter, data):
print(res)

convert values of list of dictionaries with different keys to new list of dicts

I have this list of dicts:
[{'name': 'aly', 'age': '104'},
{'name': 'Not A name', 'age': '99'}]
I want the name value to be the key and the age value to be the value of new dict.
Expected output:
['aly' : '104', 'Not A name': '99']
If you want output to be single dict, you can use dict comprehension:
output = {p["name"]: p["age"] for p in persons}
>>> {'aly': '104', 'Not A name': '99'}
If you want output to be list of dicts, you can use list comprehension:
output = [{p["name"]: p["age"]} for p in persons]
>>> [{'aly': '104'}, {'Not A name': '99'}]
You can initialize the new dict, iterate through the list and add to the new dict:
lst = [{'name': 'aly', 'age': '104'}, {'name': 'Not A name', 'age': '99'}]
newdict = {}
for item in lst:
newdict[item['name']] = item['age']
This will help you:
d = [
{'name': 'aly', 'age': '104'},
{'name': 'Not A name', 'age': '99'}
]
dict([i.values() for i in d])
# Result
{'aly': '104', 'Not A name': '99'}
# In case if you want a list of dictionary, use this
[dict([i.values() for i in d])]
# Result
[{'aly': '104', 'Not A name': '99'}]
Just a side note:
Your expected answer looks like a list (because of [ ]) but values inside the list are dictionary (key:value) which is invalid.
Here is the easiest way to convert the new list of dicts
res = list(map(lambda data: {data['name']: data['age']}, d))
print(res)

Python, difference of dict lists by comparing different fields

I have two different lists with dictionaries:
first = [{'id': '1'}, {'id': '2'}, {'id': '3'}]
second = [{'user_id': '1'}, {'user_id': '2'}]
I want something like:
# This is pseudocode
first (id) - second (user_id) = [{'id': '3'}]
Is this possible on python?
I know that it is possible by using multiple loop operators, but is there more elegant method of solving this problem, like using lambdas or something?
One way is to use a nested list comprehension as following:
In [9]: [d1 for d1 in first if not any(d2['user_id'] == d1['id'] for d2 in second)]
Out[9]: [{'id': '3'}]
But as a more Pythonic way it's better to use set operations and a list comprehension:
In [13]: f = {d['id'] for d in first}
In [14]: s = {d['user_id'] for d in second}
In [15]: result = [{'id': i} for i in f - s]
In [16]: result
Out[16]: [{'id': '3'}]
This is one approach. Using a list comprehension and lambda.
first = [{'id': '1'}, {'id': '2'}, {'id': '3'}]
second = [{'user_id': '1'}, {'user_id': '2'}]
checkVal = map(lambda d: d['user_id'], second)
print([i for i in first if i["id"] not in checkVal])
Output:
[{'id': '3'}]

string to list of dictionaries (python)

I have a string that needs to be split 3 ways and then into a list of dictionaries.
given_string = 'name:mickey,age:58|name:minnie,age:47,weight:60'
data = []
data = [value.split(',') for value in given_string.split('|')]
data = [['name:mickey', 'age:58'], ['name:minnie', 'age:47', 'weight:60']]
Now I want to split this one more time on the ':' and have the data contain a list of two dictionaries so that when I input say data[1][age], I get 47.
Basically, I think I want this for it to work:
data = [{'name': 'mickey', 'age': '58}, {'name': 'minnie', 'age': '47', 'weight': '60'}]
I believe that ultimately, data should be a list of dictionaries but once I split the string into two lists, I get confused in splitting it on the ':' and then converting the sublists to a dictionary.
You can do with a simple list comprehension
>>> [dict(x.split(':') for x in parts.split(','))
for parts in given_string.split('|')]
[{'age': '58', 'name': 'mickey'}, {'age': '47', 'name': 'minnie', 'weight': '60'}]
Nest harder.
>>> [ dict(y.split(':') for y in x.split(',')) for x in 'name:mickey,age:58|name:minnie,age:47,weight:60'.split('|')]
[{'age': '58', 'name': 'mickey'}, {'age': '47', 'name': 'minnie', 'weight': '60'}]
given_string = 'name:mickey,age:58|name:minnie,age:47,weight:60'
data = [value.split(',') for value in given_string.split('|')]
y=[] # make a empty list
for i in data:
z={}
for v in range(len(i)):
b=i[v].split(":") # ['name", "mickey', 'age","58"]
z[b[0]]=b[1] # adding keys and values in dictionary z
y.append(z) # adding dictionary to the list

Getting index of item while processing a list using map in python

While processing a list using map(), I want to access index of the item while inside lambda. How can I do that?
For example
ranked_users = ['jon','bob','jane','alice','chris']
user_details = map(lambda x: {'name':x, 'rank':?}, ranked_users)
How can I get rank of each user in above example?
Use enumerate:
In [3]: user_details = [{'name':x, 'rank':i} for i,x in enumerate(ranked_users)]
In [4]: user_details
Out[4]:
[{'name': 'jon', 'rank': 0},
{'name': 'bob', 'rank': 1},
{'name': 'jane', 'rank': 2},
{'name': 'alice', 'rank': 3},
{'name': 'chris', 'rank': 4}]
PS. My first answer was
user_details = map(lambda (i,x): {'name':x, 'rank':i}, enumerate(ranked_users))
I'd strongly recommend using a list comprehension or generator expression over map and lambda whenever possible. List comprehensions are more readable, and tend to be faster to boot.
Alternatively you could use a list comprehension rather than map() and lambda.
ranked_users = ['jon','bob','jane','alice','chris']
user_details = [{'name' : x, 'rank' : ranked_users.index(x)} for x in ranked_users]
Output:
[{'name': 'jon', 'rank': 0}, {'name': 'bob', 'rank': 1}, {'name': 'jane', 'rank': 2}, {'name': 'alice', 'rank': 3}, {'name': 'chris', 'rank': 4}]
List comprehensions are very powerful and are also faster than a combination of map and lambda.
In my opinion the question was about map function and preferred answer is partly correct due to syntax error caused by putting tuple argument to lambda lambda (i,x)
idea of enumerate is nice and proper solution would be:
map(lambda x: {'name':x[1], 'rank':x[0]}, enumerate(ranked_users))
and some timing to compare speed with comprehension:
def with_map():
ranked_users = range(10 ** 6)
list(map(lambda x: {'name': x[1], 'rank': x[0]}, enumerate(ranked_users)))
def by_comprehension():
ranked_users = range(10 ** 6)
[{'name': x, 'rank': i} for i, x in enumerate(ranked_users)]
from timeit import timeit
time_with_map = timeit(with_map, number=10)
time_with_comprehension = timeit(by_comprehension, number=10)
print('list comprehension is about %.2f x faster than map in this test case' % (time_with_map/time_with_comprehension))
test result: list comprehension is about 1.31 x faster than map in this test case
Actually here is a more elegant, verbose solution than using an enumerate tuple in the map (because of tuple indexing). Map can take more iterables as arguments so let's use it.
map(lambda user, user_id: (user_id, user), ranked_users, range(ranked_users.__len__()))

Categories