I have a list of dictionaries in Python and I want to check if an dictionary entry exists for a specific term. It works using the syntax
if any(d['acronym'] == 'lol' for d in loaded_data):
print "found"
but I also want to get the value stored at this key, I mean d['acronym']['meaning']. My problem is that when I try to print it out Python does not know about d. Any suggestions, maybe how can I get the index of the occurence without looping again through all the list? Thanks!
If you know there's at most one match (or, alternatively, that you only care about the first) you can use next:
>>> loaded_data = [{"acronym": "AUP", "meaning": "Always Use Python"}, {"acronym": "GNDN", "meaning": "Goes Nowhere, Does Nothing"}]
>>> next(d for d in loaded_data if d['acronym'] == 'AUP')
{'acronym': 'AUP', 'meaning': 'Always Use Python'}
And then depending on whether you want an exception or None as the not-found value:
>>> next(d for d in loaded_data if d['acronym'] == 'AZZ')
Traceback (most recent call last):
File "<ipython-input-18-27ec09ac3228>", line 1, in <module>
next(d for d in loaded_data if d['acronym'] == 'AZZ')
StopIteration
>>> next((d for d in loaded_data if d['acronym'] == 'AZZ'), None)
>>>
You could even get the value and not the dict directly, if you wanted:
>>> next((d['meaning'] for d in loaded_data if d['acronym'] == 'GNDN'), None)
'Goes Nowhere, Does Nothing'
You can just use filter function:
filter(lambda d: d['acronym'] == 'lol', loaded_data)
That will return a list of dictionaries containing acronym == lol:
l = filter(lambda d: d['acronym'] == 'lol', loaded_data)
if l:
print "found"
print l[0]
Don't even need to use any function at all.
If you want to use the item, rather than just check that it's there:
for d in loaded_data:
if d['acronym'] == 'lol':
print("found")
# use d
break # skip the rest of loaded_data
any() only gives you back a boolean, so you can't use that. So just write a loop:
for d in loaded_data:
if d['acronym'] == 'lol':
print "found"
meaning = d['meaning']
break
else:
# The else: of a for runs only if the loop finished without break
print "not found"
meaning = None
Edit: or change it into a slightly more generic function:
def first(iterable, condition):
# Return first element of iterable for which condition is True
for element in iterable:
if condition(element):
return element
return None
found_d = first(loaded_data, lambda d: d['acronym'] == 'lol')
if found_d:
print "found"
# Use found_d
firstone = next((d for d in loaded_data if d['acronym'] == 'lol'), None)
gives you the first dict where the condition applies, or None if there is no such dict.
Related
below is my list of dictionaries:
I'm tried to remove the duplicate values from 'r_id'. some values are in list and some are in string.
list_of_dict = [{'fid':200, 'r_id':['4321', '4321']}, {'fid':201, 'r_id':'5321'}]
expected output
list_of_dict = [{'fid':200, 'r_id':['4321']}, {'fid':201, 'r_id':['5321']}]
I've tried below piece of code but not worked
for item in list_of_dict:
if type(item["record_id"]) == list:
item["record_id"] = [set(item["record_id"])]
please suggest me with the solution
Do:
result = [{ "fid" : d["fid"] , "r_id" : list(set(d["r_id"])) } for d in list_of_dict]
print(result)
Or simply:
for d in list_of_dict:
d["r_id"] = list(set(d["r_id"]))
print(list_of_dict)
If you really need to check the type, use isinstance:
for d in list_of_dict:
if isinstance(d["r_id"], list):
d["r_id"] = list(set(d["r_id"]))
For the canonical way of checking type in Python, read this.
If in item['r_id'] you have another type like str you can try this:
list_of_dict = [{'fid':201, 'r_id':'5321'}, {'fid':200, 'r_id':['4321', '4321']}]
for item in list_of_dict:
if type (item['r_id']) == list:
# if isinstance(item['r_id'],list):
item['r_id'] = list(set(item['r_id']))
elif type (item['r_id']) == str:
# elif isinstance(item['r_id'],str):
item['r_id'] = [item['r_id']]
#Shortest approach
>>> [{'fid' : item['fid'], 'r_id' : list(set(item['r_id'])) if type(item['r_id']) == list else [item['r_id']]} for item in list_of_dict]
[{'fid': 201, 'r_id': ['5321']}, {'fid': 200, 'r_id': ['4321']}]
You are almost there !
Though there may be other (better) solutions, your solution will also work if you change it as below:
for item in list_of_dict:
if type(item["r_id"]) == list:
item["r_id"] = list(set(item["r_id"]))
try this:
for items in list_of_dict:
temp_list = list()
if isinstance(item["r_id"], list):
for value in item["r_id"]:
if value not in templist:
temp_list.append(value)
item["r_id"] = temp_list
I have a more different type of keys in dict (there is no need to type values too)
'PL-1/KK-1/FO-1'
'PL-1/KK-2/GH-3'
'PL-1/KK-2'
'PL-1/KK-1/FO-4'
And I need a condition
if exist (key.split('/')[2])
do something
return data
else:
do something
return data
Desired output:
In the first condition, all keys make entries except 'PL-1/KK-2'.
Is there in python something like 'exist'?
No, there is no 'exists' operator.
In your case you should just test slashes:
if key.count('/') >= 2:
# ...
If you need to have the components of the key, store and test the length:
components = key.split('/')
if len(components) >= 2:
# ...
def has_key(i_dict, i_filter):
return any(k for k in i_dict.iterkeys() if i_filter(k))
# be it a dict called my_dict
# you could call it like
has_key(my_dict, lambda x: x.count("/") == 2)
# or
has_key(my_dict, lambda x: len(x.split("/"))==2)
here's a little test
>>> my_dict = {"a":1,"c":3}
>>> has_key(my_dict, lambda k:k=="a")
True
>>> has_key(my_dict, lambda k:k=="c")
True
>>> has_key(my_dict, lambda k:k=="x")
False
I am using list in my first python project.
data_items = [{"ID":0x1111, "Description":"data1", "Writable":"FALSE"},
{"ID":0x2222, "Description":"data2", "Writable":"TRUE"},
{"ID":0x3333, "Description":"data3", "Writable":"FALSE"},
{"ID":0x4444, "Description":"data4", "Writable":"TRUE"}]
I want to use another list name "new_data_items" and display only TRUE conditions like below example:How to write for loop for this
new_data_items = [{"ID":0x2222, "Description":"data2", "Writable":"TRUE"},
{"ID":0x4444, "Description":"data4", "Writable":"TRUE"}]
You can use filter to do that:
filter(lambda x: x['Writable'] == 'TRUE', data_items)
Note that filter returns an iterator so you may also want to convert that to a list:
list(filter(lambda x: x['Writable'] == 'TRUE', data_items))
If the 'Writable' field may not be present for some records replace indexing with .get:
list(filter(lambda x: x.get('Writable') == 'TRUE', data_items))
use python list compression
[_ for _ in data_items if _.get('Writable') == 'TRUE']
Chk this link : https://repl.it/HEyl/0
You could do something like the following:
new_data_items = []
for item in data_items:
if item['Writable'] == 'TRUE':
new_data_items.append(item)
But list comprehensions would be quicker and less verbose:
new_data_items = [item for item in data_items if item['Writable'] == 'TRUE']
data_items = [{"ID":0x1111, "Description":"data1", "Writable":"FALSE"},
{"ID":0x2222, "Description":"data2", "Writable":"TRUE"},
{"ID":0x3333, "Description":"data3", "Writable":"FALSE"},
{"ID":0x4444, "Description":"data4", "Writable":"TRUE"}]
new_data = list()
for element in data_items:
value = element.get('Writable')
if not value == "FALSE":
new_data.append(element)
print new_data
hey i have a Problem solving a Problem
that Looks like this:
the Output is exactly what i need but i wonder is there isnt a more elegant
way to do that?
list = [["key189","0","apples"],
["key622","1","bananas"],
["key233","2","bacon"],
["key454","3","bread"],
["key35","4","jam"],
["key6","5","coffee"]]
for e in list:
if e[0] == "key622":
key622 = e[2]
if e[0] == "key189":
key189 = e[2]
if e[0] == "key35":
key35 = e[2]
if e[0] == "key454":
key454 = e[2]
if e[0] == "key233":
key233 = e[2]
if e[0] == "key6":
key6 = e[2]
string_form = "|".join([key6, key35, key233, key189, key622, key454])
print(string_form)
# prints coffee|jam|bacon|apples|bananas|bread
I think a using a dictionary will make your life easier.
dt = {itm[0]:itm[2] for itm in list}
dt will be:
{'key189': 'apples',
'key233': 'bacon',
'key35': 'jam',
'key454': 'bread',
'key6': 'coffee',
'key622': 'bananas'}
string_form = "|".join(dt.values())
string_form will be:
'coffee|apples|bacon|jam|bananas|bread'
you can get any key's value: like this:
dt.get('key35')
For the specific string use this:
"|".join([dt.get('key6'), dt.get('key35'), dt.get('key233'), dt.get('key189'), dt.get('key622'), dt.get('key454')])
Try not to use variable names like list, dict etc.
Since you didn't specify anything about order, this should do:
data = [["key189","0","apples"],
["key622","1","bananas"],
["key233","2","bacon"],
["key454","3","bread"],
["key35","4","jam"],
["key6","5","coffee"]]
print("|".join([pair[2] for pair in data]))
"|".join(fruit for _, _, fruit in list)
Instead of hardcording the order in an if-else construct, you could just define it in a list, and then sort according to the index the item has in that list:
order = ['key6', 'key35', 'key238', 'key189', 'key622', 'key454']
print("|".join(y[2] for y in sorted([x for x in lst if x[0] in order], key = lambda i: order.index(i[0]))))
Python noob so I might be going about this the wrong way
I want to use a try/except block to find if a value in a dict isn't set like
try:
if entry['VALUE1'] == None: void()
if entry['VALUE2'] == None: void()
except KeyError:
print "Values not Found"
Of course the 'void' function doesn't exist, is there anything I can do to get round this so that code will work properly
Try replacing void() with pass.
Of course, in practice, you can just do if key in some_dict:. But if you ever need a "do nothing" in a block, pass is what you're looking for.
Try:
if "VALUE1" in entry:
foo()
to determine if the "VALUE1" string is in the set of keys of the entry dict.
Your logic would probably look something like:
if "VALUE1" not in entry or "VALUE2" not in entry:
print "Values not found"
The try block is completely unnecessary for this test.
if entry.has_key('VALUE1'):
do_something()
or
if 'VALUE1' in entry:
do_something()
I would suggest making a function to help you out:
contains_all_keys = lambda d, keys: reduce(lambda a, b: a and b, map(lambda k: k in d, keys))
di = {'a':'some val', 'b':'some other val'}
if contains_all_keys(di, ['a', 'b']):
print 'a and b present'
if not contains_all_keys(di, ['a', 'b', 'c']):
print 'missing keys'
If you just want to evoke the exception, through a key lookup, the if is not neccesary. It's sufficient to just express the lookup on a line by itself, such as:
>>> a = {}
>>> a['value']
Traceback (most recent call last):
File "<ipython console>", line 1, in <module>
KeyError: 'value'
>>>