How can I add a condition in list comprehension like this? Ex:
Ex:
[dict if dict not in THIS.LIST for dict in tempList]
You had the order wrong, move the if to the end.
[dict for dict in tempList if dict not in THIS.LIST ]
Using your method python expects an else:
[dict if dict not in THIS.LIST else whatever for dict in tempList]
If you want to refer to the actual list you are creating use a for loop, if the items were hashable you could use a set to check if the element had already been seen with 0(1) lookups but if you have dicts then you won't be able to use a set with the dict directly:
res = []
for dct in temp_list:
if dct not in res:
res.append(dct)
Or a similar approach using a list comp, check from start of the list to the current index:
print([dct for ind, dct in enumerate(temp_list) if dct not in temp_list[:ind]])
If you just want to remove duplicate dicts we can use the dict.items:
temp_list = [ {1:2},{1:2}]
print([dict(items) for items in set(tuple(dct.items()) for dct in temp_list) ])
Or use an OrderedDict to keep order:
from collections import OrderedDict
temp_list = [ {1:2},{1:2}]
print(list(OrderedDict(((tuple(dct.items()),dct) for dct in temp_list)).values()))
Or again use a normal loop:
temp_list = [ {1:2},{1:2}]
seen = set()
out = []
for dct in temp_list:
tup = tuple(dct.items())
if tup not in seen:
out.append(dct)
seen.add(tup)
print(out)
Related
Here I have a list like this.
ls = ['Small:u', 'Small:o']
What I want is to create a dictionary of each list items like this.
dict1 = {'Small':'u'}
dict2 = {'Small':'o'}
How can I do it ? Is it possible?
>>> x = [dict([pair.split(":", 1)]) for pair in ['Small:u', 'Small:o']]
>>> x
[{'Small': 'u'}, {'Small': 'o'}]
Yes, it is possible, but one thing I'm not sure whether is possible (or a good idea at all) is to programmatically assign variable names to new dictionaries, so instead the easier way is to create a dictionary of dictionaries:
dic_of_dics = {}
for index, item in enumerate(ls):
i, j = item.split(':')
dic_of_dics[f'dict{index}'] = {i : j}
This is another way:
ls = ['Small:u', 'Small:o']
dict_list = []
for i in ls:
k, v = i.split(':')
dict_list.append({k: v})
print(dict_list)
print(dict_list[1].values())
Perhaps with minimal line:
ls = ['Small:u', 'Small:o']
dict_list = map(lambda x:dict([x.split(':')]), ls)
# for python3: print(list(dict_list))
# for Python2: print(dict_list)
Explanation: I am using map function to convert the list of string to list of lists. Then I am passing it through dict(to convert them to dictionary).
I am accessing a list of dictionary items list_of_dict = [{'ka':'1a', 'kb':'1b', 'kc':'1c'},{'ka':'2a'},{'ka':'3a', 'kb':'3b', 'kc':'3c'}], and trying to conditionally append each entry to another list article_list using a function add_entries.
My desired output
article_list = [{x:1a, y:1b, z:1c}, {x:2a}, {x:3a, y:3b, z:3c}]
My code:
def add_entries(list_of_dict):
keys = ['x','y','z']
#defining a temporary dictionary here
my_dict = dict.fromkeys(keys,0)
entry_keys = ['ka','kb','kc']
my_list = []
for item in list_of_dict:
# conditionally append the entries into the temporary dictionary maintaining desired key names
my_dict.update({a: item[b] for a,b in zip(keys, entry_keys) if b in item})
my_list.append(my_dict)
return my_list
if __name__ == "__main__":
list_of_dict = [{'ka':'1a', 'kb':'1b', 'kc':'1c'},{'ka':'2a'},{'ka':'3a', 'kb':'3b', 'kc':'3c'}]
article_list = []
returned_list = add_entries(list_of_dict)
article_list.extend(returned_list)
My output
article_list = [{x:3a, y:3b, z:3c}, {x:3a, y:3b, z:3c}, {x:3a, y:3b, z:3c}]
Whats wrong
my_list.append(my_dict) appends a reference to the my_dict object to my_list. Therefore, at the end of the for loop in your example, my_list is a list of references to the exact same dictionary in memory.
You can see this for yourself using the function id. id, at least in CPython, basically gives you the memory address of an object. If you do
article_list.extend(returned_list)
print([id(d) for d in article_list])
You'll get a list of identical memory addresses. On my machine I get
[139920570625792, 139920570625792, 139920570625792]
The consequence is that updating the dictionary affects 'all of the dictionaries' in your list. (quotes because really there are not multiple dictionaries in your list, just many times the exact same one). So in the end, only the last update operation is visible to you.
A good discussion on references and objects in Python can be found in this answer https://stackoverflow.com/a/30340596/8791491
The fix
Moving the definition of my_dict inside the for loop, means that you get a new, separate dictionary for each element of my_list. Now, the update operation won't affect the other dictionaries in the list, and my_list is a list of references to several different dictionaries.
def add_entries(list_of_dict):
keys = ['x','y','z']
entry_keys = ['ka','kb','kc']
my_list = []
for item in list_of_dict:
#defining a new dictionary here
my_dict = dict.fromkeys(keys,0)
# conditionally append the entries into the temporary dictionary maintaining desired key names
my_dict.update({a: item[b] for a,b in zip(keys, entry_keys) if b in item})
my_list.append(my_dict)
return my_list
You can use this.
keys=['x','y','z']
res=[{k1:d[k]} for d in list_of_dict for k,k1 in zip(d,keys)]
output
[{'x': '1a'},
{'y': '1b'},
{'z': '1c'},
{'x': '2a'},
{'x': '3a'},
{'y': '3b'},
{'z': '3c'}]
Try this:
list_new_d=[]
for d in list_of_dict:
new_d={}
for k,v in d.items():
if k == 'ka':
new_d['x'] = v
if k == 'kb':
new_d['y'] = v
if k == 'kc':
new_d['z'] = v
list_new_d.append(new_d)
I have this list of tuples.
List = [('id1', 'name1', 'date1'), ('id1', 'name2', 'date2'), ('id2', 'name3', 'date3'), ('id2', 'name4', 'date4')]
I want to have a function that converts list to become a dictionary such that
Dict = convert('id1', List)
Contents of Dict is {'id1':('name1', 'name2')}
The first parameter filters out the tuples that are of interest based on the first element. It is also the key of the output dictionary. The 2nd element of each tuple will become the values of the output dictionary.
I wrote a little function in Python and it does not work. Thank you very much for your help if you have better suggestions. Forget about my function if it is too far out which I think so. Solving it in a pythonic way is most welcome. I am using Python 2.7
def convertToDict(key, List):
for key in List[0]:
DictOut = {key:[]}
DictOut[key].append(List[0])
You are replacing the DictOut unconditionally. Instead you should be using setdefault like this
DictOut.setdefault(key, [])
Your program can be written like this
def convertToDict(my_list):
result_dict = {}
for item in my_list:
result_dict.setdefault(item[0], []).append(item[1])
return result_dict
print convertToDict(my_list)
# {'id2': ['name3', 'name4'], 'id1': ['name1', 'name2']}
If you want to get only the specific keys. you can use this
def convertToDict(key, my_list):
result_dict = {}
for item in my_list:
if item[0] == key:
result_dict.setdefault(item[0], []).append(item[1])
return result_dict
print convertToDict("id1", my_list)
# {'id1': ['name1', 'name2']}
You can actually use collections.defaultdict for this purpose, like this
from collections import defaultdict
def convertToDict(key, my_list):
result_dict = defaultdict(list)
for item in my_list:
if item[0] == key:
result_dict[item[0]].append(item[1])
return result_dict
print convertToDict("id1", my_list)
Python novice here. I have a dictionary of lists, like so:
d = {
1: ['foo', 'foo(1)', 'bar', 'bar(1)'],
2: ['foobaz', 'foobaz(1)', 'apple', 'apple(1)'],
3: ['oz', 'oz(1)', 'boo', 'boo(1)']
}
I am trying to figure out how to loop through the keys of the dictionary and the corresponding list values and remove all strings in each in list with a parantheses tail. So far this is what I have:
for key in keys:
for word in d[key]...: # what else needs to go here?
regex = re.compile('\w+\([0-9]\)')
re.sub(regex, '', word) # Should this be a ".pop()" from list instead?
I would like to do this with a list comprehension, but as I said, I can't find much information on looping through dict keys and corresponding dict value of lists. What's the most efficient way of setting this up?
You can re-build the dictionary, letting only elements without parenthesis through:
d = {k:[elem for elem in v if not elem.endswith(')')] for k,v in d.iteritems()}
temp_dict = d
for key, value is temp_dict:
for elem in value:
if temp_dict[key][elem].find(")")!=-1:
d[key].remove[elem]
you can't edit a list while iterating over it, so you create a copy of your list as temp_list and if you find parenthesis tail in it, you delete corresponding element from your original list.
Alternatively, you can do it without rebuilding the dictionary, which may be preferable if it's huge...
for k, v in d.iteritems():
d[k] = filter(lambda x: not x.endswith(')'), v)
I have a list of dictionaries such as:
[{'mykey1':'myvalue1', 'mykey2':'myvalue2'}, {'mykey1':'myvalue1a', 'mykey2':'myvalue2a'}]
I need to remove all key values pairs from all dictionaries where the key is equal to mykey1. I could do this by looping through and using the del statement, but I am wondering how I would create a new list using list comprehensions or lambdas which would just remove all key value pairs where the key was mykey1.
Many thanks
If you really want to use a list comprehension, combine it with a dict comprehension:
[{k: v for k, v in d.iteritems() if k != 'mykey1'} for d in mylist]
Substitute .iteritems() for .items() if you are on python 3.
On python 2.6 and below you should use:
[dict((k, v) for k, v in d.iteritems() if k != 'mykey1') for d in mylist]
as the {key: value ...} dict comprehension syntax was only introduced in Python 2.7 and 3.
def new_dict(old_dict):
n = old_dict.copy()
n.pop('mykey1',None)
return n
new_list_of_dict = map(new_dict,list_of_dict)
or
new_list_of_dict = [ new_dict(d) for d in list_of_dict ]
Rather than using del, I opted for dict.pop since pop will suppress the KeyError if the key doesn't exist.
If you really only want to get certain keys, this becomes a bit easier.
from operator import itemgetter
tuple_keys = ('key1','key2','key3')
get_keys = itemgetter(*tuple_keys)
new_dict_list = [ dict(zip(tuple_keys,get_keys(d)) for d in old_dict_list ]
which raises KeyError if the keys aren't in the old dict
Or:
new_dict_list = [ dict( (k,d.get(k,None)) for k in tuple_keys ) for d in old_dict_list ]
which will also add key:None if key isn't in the old dict. If you don't want that None, you could do:
new_dict_list = [ dict( (k,d[k]) for k in tuple_keys if k in d) for d in old_dict_list ]
Depending on what percent of the dictionary you're including/excluding and the size of the dictionaries, this might be slightly faster than the solution by #MartijnPieters.
You can follow this simple step :
arr = [{'mykey1':'myvalue1', 'mykey2':'myvalue2'}, {'mykey1':'myvalue1a', 'mykey2':'myvalue2a'}]
for i in arr:
del i["mykey1"]
print(arr)
output:
[{'mykey2': 'myvalue2'}, {'mykey2': 'myvalue2a'}]
On python 3.5 this works successfully
'''result is my list dict'''
[{key: value for key, value in dict.items() if key != 'EQUITY'} for dict in result]
[d.pop('mykey1', None) for d in list]