Correct list comprehension is [[(k,v) for k,v in d.items()] for d in ld]
Demo:
>>> ld = [{'a': 10, 'b': 20}, {'p': 10, 'u': 100}]
>>> [[(k,v) for k,v in d.items()] for d in ld]
[[('a', 10), ('b', 20)], [('p', 10), ('u', 100)]]
>>> [[(k,v) for k,v in d.items() if k not in ['b','u']] for d in ld]
[[('a', 10)], [('p', 10)]]
Answer from Irshad Bhat on Stack OverflowCorrect list comprehension is [[(k,v) for k,v in d.items()] for d in ld]
Demo:
>>> ld = [{'a': 10, 'b': 20}, {'p': 10, 'u': 100}]
>>> [[(k,v) for k,v in d.items()] for d in ld]
[[('a', 10), ('b', 20)], [('p', 10), ('u', 100)]]
>>> [[(k,v) for k,v in d.items() if k not in ['b','u']] for d in ld]
[[('a', 10)], [('p', 10)]]
It looks like you want a list of tuples with the keys and values paired.
To do this you can do two for loops in a list comprehension, and use .items() to output the keys and values as tuples:
[kv for d in ld for kv in d.items()]
outputs:
[('a', 10), ('b', 20), ('p', 10), ('u', 100)]
Original data:
list_of_dictionaries = [{'key1':'value1'},{'key2':'value2'},{'key3':['item1','item2','item3']}]Desired output
{'key1':'value1','key2':'value2','key3': ['item1','item2','item3']}Standart loop does the job, but i don't like it
empty_dictionary = {}
for item in list_of_dictionaries:
for k, v in item.items():
empty_dictionary[k] = vHow can i do it using list comprehension?
Python list comprehension for dictionaries in dictionaries? - Stack Overflow
Python Dictionary comprehension for a list of dictionaries - Stack Overflow
Python dictionary comprehension on a list of dictionaries - Stack Overflow
python - Python3 Dictionary Comprehension - Stack Overflow
Can't claim it's more "concise", but it's a dict comprehension in the end :D
from itertools import groupby
from operator import itemgetter
sort_list = sorted(file_list, key=itemgetter('size'))
groups = groupby(sort_list, key=itemgetter('size'))
print({k:[i['path'] for i in g] for k, g in groups})
If, for some reason, you want to avoid the import of defaultdict, this is one way to do it:
import json
file_list = [
{'path': '/path/to/file1', 'size': 100, 'time': '2022-02-15'},
{'path': '/path/to/file2', 'size': 200, 'time': '2022-02-13'},
{'path': '/path/to/file3', 'size': 300, 'time': '2022-02-12'},
{'path': '/path/to/file4', 'size': 200, 'time': '2022-02-11'},
{'path': '/path/to/file5', 'size': 100, 'time': '2022-02-1-'}]
new_dict = {}
for file in file_list:
new_dict[file['size']] = (files := new_dict.get(file['size'], []))
files.append(file['path'])
print(json.dumps(new_dict, indent=4, sort_keys=True))
And if you don't like the constant reassignment of that list to the dicrionary entry (I don't really):
for file in file_list:
if file['size'] not in new_dict:
new_dict[file['size']] = []
new_dict[file['size']].append(file['path'])
(Note that the default indent depth for Python is 4, you would do others and your future self a favour by adopting that sooner rather than later)
As indicated in the comments, a perhaps more elegant solution:
for file in file_list:
new_dict.setdefault(file['size'], []).append(file['path'])
However, although it's possible to come up with a single line comprehension, it won't be more efficient, faster, or readable. In fact, likely none of those - so what would be the point?
Shorter code is often better code if it doesn't compromise on function or readability, but should never be a goal by itself.
For example, consider this (bad) example:
c_dict = {size: [fp['path'] for fp in file_list if fp['size'] == size] for size in set(fs['size'] for fs in file_list)}
And although that's a single line, you'd probably want to write it like this for readability, at which point you just have more code than before:
c_dict = {
size: [fp['path'] for fp in file_list if fp['size'] == size]
for size in set(fs['size'] for fs in file_list)
}
You can do this:
Use with AIs = dict([ (k,r) for k,r in mydict.iteritems() if r['x'] > 92 and r['x'] < 95 and r['y'] > 70 and r['y'] < 75 ])
This takes a dict as you specified and returns a 'filtered' dict.
If dct is
Use with AI{'test1420': {'y': '060', 'x': '070', 'fname': 'test1420'},
'test277': {'y': 72, 'x': 94, 'fname': 'test277'},}
Perhaps you are looking for something like:
Use with AI[ subdct for key,subdct in dct.iteritems()
if 92<subdct['x']<95 and 70<subdct['y']<75 ]
A little nicety is that Python allows you to chain inequalities:
Use with AI92<dct[key]['x']<95
instead of
Use with AIif r['x'] > 92 and r['x'] < 95
Note also that above I've written a list comprehension, so you get back a list (in this case, of dicts).
In Python3 there are such things as dict comprehensions as well:
Use with AI{ n: n*n for n in range(5) } # dict comprehension
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
In Python2 the equivalent would be
Use with AIdict( (n,n*n) for n in range(5) )
I'm not sure if you are looking for a list of dicts or a dict of dicts, but if you understand the examples above, it is easy to modify my answer to get what you want.
in_list = [{'fips': '01001', 'state': 'AL', 'name': 'Autauga County'},
{'fips': '20005', 'state': 'KS', 'name': 'Atchison County'},
{'fips': '47145', 'state': 'TN', 'name': 'Roane County'}]
out_dict = {x['name']: 'United States' for x in in_list if 'name' in x}
Some notes for learning:
- Comprehensions are only for Python 2.7 onwards
- Dictionary comprehensions are very similar to list comprehensions except with curly braces
{}(and keys) - In case you didn't know, you can also add more complicated control-flow after the for loop in a comprehension such as
[x for x in some_list if (cond)]
For completeness, if you can't use comprehensions, try this
out_dict = {}
for dict_item in in_list:
if not isinstance(dict_item, dict):
continue
if 'name' in dict_item:
in_name = dict_item['name']
out_dict[in_name] = 'United States'
As mentioned in the comments, for Python 2.6 you can replace the {k: v for k,v in iterator} with:
dict((k,v) for k,v in iterator)
You can read more about this in this question
Happy Coding!
Here's a little solution working for both python2.7.x and python 3.x:
data = [
{'fips': '01001', 'state': 'AL', 'name': 'Autauga County'},
{'fips': '20005', 'state': 'KS', 'name': 'Atchison County'},
{'fips': '47145', 'state': 'TN', 'name': 'Roane County'},
{'fips': 'xxx', 'state': 'yyy'}
]
output = {item['name']: 'United States' for item in data if 'name' in item}
print(output)
Note how each line only differs by the key used. This means that the keys should be iterated over:
list_of_dictionaries = [{1: 2, 2: 3}, {1: 4, 2: 5}, {1: 6, 2: 7}]
# Only safe if you know there will always be at least one dictionary
keys = list_of_dictionaries[0].keys()
dictionary_of_lists = \
{k: [i[k] for i in list_of_dictionaries]
for k in keys} # A second level of iteration to automate what you were doing manually before
print(dictionary_of_lists)
>>> {1: [2, 4, 6], 2: [3, 5, 7]}
If you are allowed to use pandas, this is a much simpler solution.
Using pandas, here's what you will get:
import pandas as pd
list_of_dicts = [{'k1':'v1', 'k2':'v2'}, {'k1':'v3', 'k2':'v4'},
{'k1':'v5', 'k2':'v6'}, {'k1':'v7', 'k2':'v8'},
{'k1':'v9', 'k2':'v10'}]
df = pd.DataFrame(list_of_dicts)
k = {c:df[c].tolist() for c in df.columns}
print (k)
The output of this will be:
{'k1': ['v1', 'v3', 'v5', 'v7', 'v9'], 'k2': ['v2', 'v4', 'v6', 'v8', 'v10']}
With this approach, you can keep adding as many keys as you like, the solution will be same.
import pandas as pd
list_of_dicts = [{'k1':'v1' , 'k2':'v2' , 'k3': 'v3'},
{'k1':'v4' , 'k2':'v5' , 'k3': 'v6'},
{'k1':'v7' , 'k2':'v8' , 'k3': 'v9'},
{'k1':'v10', 'k2':'v11', 'k3': 'v12'},
{'k1':'v13' ,'k2':'v14', 'k3': 'v15'}]
df = pd.DataFrame(list_of_dicts)
k = {c:df[c].tolist() for c in df.columns}
print (k)
This will result in:
{'k1': ['v1', 'v4', 'v7', 'v10', 'v13'], 'k2': ['v2', 'v5', 'v8', 'v11', 'v14'], 'k3': ['v3', 'v6', 'v9', 'v12', 'v15']}
The only limitation is that each set of dicts have to have same number of elements (k1, k2, k3). You cannot have (k1,k2) and (k1,k2,k3). Then the code will break as the dataframe is looking for same number of elements per column.
Use a dict comprehension (Python 2.7 and later):
Use with AI{key: value for key, value in zip(keys, values)}
Alternatively, use the dict constructor:
Use with AIpairs = [('a', 1), ('b', 2)]
dict(pairs) # โ {'a': 1, 'b': 2}
dict((k, v + 10) for k, v in pairs) # โ {'a': 11, 'b': 12}
Given separate lists of keys and values, use the dict constructor with zip:
Use with AIkeys = ['a', 'b']
values = [1, 2]
dict(zip(keys, values)) # โ {'a': 1, 'b': 2}
In Python 3 and Python 2.7+, dictionary comprehensions look like the below:
Use with AId = {k:v for k, v in iterable}
For Python 2.6 or earlier, see fortran's answer.
[elem['a'] for elem in alist if 'a' in elem]
might be a clearer way of phrasing what you have above.
The "for elem in alist" part will iterate over alist, allowing this to look through each dictionary in alist.
Then, the "if 'a' in elem" will ensure that the key 'a' is in the dictionary before the lookup occurs, so that you don't get a KeyError from trying to look up an element that doesn't exist in the dictionary.
Finally, taking elem['a'] gives you the value in each dictionary with key 'a'. This whole statement will then give the list of values in each of the dictionaries with key 'a'.
Hope this makes it a bit clearer.
You can do:
alist=[{'a':'1a', 'b':'1b'},{'a':'2a','b':'2b'}, {'a':'3a','b':'3b'}]
new_list = [a.get('a') for a in alist]
If you want to restrict it only to dictionary with a key a,
new_list = [a.get('a') for a in alist if a.get('a')]
Based on gnibbler's suggestion:
new_list = [a.get('a') for a in alist if 'a' in a ]
You can use Counter with sum:
from collections import Counter
allChannelTraffic = [{"Web": 4, "android": 3}, {"Web": 1}, {"Web": 1}, {"Web": 1}, ]
result = sum(map(Counter, allChannelTraffic), Counter())
print(result)
Output
Counter({'Web': 7, 'android': 3})
List comprehensions are not really useful here.
Generator expressions instead allows us to do the following:
allChannelTraffic = [ { "Web" : 4, "android" : 3 }, { "Web" : 1 }, { "Web" : 1 }, { "Web" : 1 },]
keys = set(k for d in allChannelTraffic for k in d.keys())
totals = {key: sum(d.get(key, 0) for d in allChannelTraffic) for key in keys}
print(totals)
# {'Web': 7, 'android': 3}
That last one {key: sum([...]) for key in keys} is a dictionary comprehension by the way.
And I could have used a set comprehension instead of the set() in line 2:
{k ... for k in d.keys()} == set(k ... for k in d.keys())
But I'd rather not do that, since the set() is much clearer for the reader.
In general though the Counter or Defaultdict approach for your problem might be more understandable for unexperienced pythonistas....
I'm trying to create the following dictionary:
{ 0:3,0:4,0:5 }
And I did:
{ 0:i for i in range(3,6) }
Which doesn't work. Any idea how to? Maybe I can make it through a list of pairs? But is this way possible?