Grabbing a dictionary given just a few keys and values - python-2.7

Suppose I have a list of dictionaries, all of which have the same keys. An instance of such a dictionary in the list might look like:
dict = {"Height": 6.0, "Weight": 201.5, "Name": "John", "Status": "Married"}
Given only a few (key, value) pairs, I want to extract all dictionaries satisfying those pairs. For example, if I have
attributes = {"Height": 5.5, "Name": "John"}
I want to extract all dictionaries whose height value is greater than or equal to 5.5 AND whose name value is John.
I'm able to write the code that can satisfy one OR the other, but dealing with mixed types (float and string) is throwing me off, so my AND operator is being confused I guess. The problem part of my code, for example, is:
for option in attributes.keys():
if dict[option] == attributes[option] and dict[option] >= attributes[option]
print dict

If you have multiple different condition you have to do all of them, but instead of using and you can use all built-in function and a function for filtering the dictionaries, then use it within a list comprehension or filter function in order to get the expected dictionaries.
from operator import itemgetter
option1, option2, option3 = itemgetter(key1, key2, key3)(attributes)
def filter_func(temp_dict):
# key1, key2, key3 have been defined already (keys in attributes)
val1, val2, val3 = itemgetter(key1, key2, key3)(temp_dict)
return all(option1 == val1, option2 => val2, option3 => val3)
filtered_result = filter(filter_func, list_of_dictionaries)
Also note that if it's possible that the dictionaries with your list don't have all the specified keys, the itemgetter might raise an KeyError for getting ride of that you can use dict.get attribute by passing a default value to it (based on your need).
For example for val3 you can use temp_dict.get(key3, 0).

Related

Django convert String in Dictionary to Integer for the first 3 keys

Sorry for this newbie questions.
I have a dict like this:
{'id':'1', 'Book':'21', 'Member':'3', 'Title':'Chameleon vol. 2',
'Author':'Jason Bridge'}
I want to convert that dict to:
{'id':1, 'Book':21, 'Member':3, 'Title':'Chameleon vol. 2',
'Author':'Jason Bridge'}
I need to convert only the first 3 key value to int
Thanks in advance
dict1 = {'id':'1', 'Book':'21', 'Member':'3', 'Title':'Chameleon vol. 2', 'Author':'Jason Bridge'}
y_dict = dict(list(dict1.items())[:3])
print(y_dict) #dict sliced to the first 3 items that their values will be converted
z_dict = dict(list(dict1.items())[3:])
print(z_dict) #the rest of item that their values will not be converted to integer
x_dict = {k:int(v) for k, v in y_dict.items()}
print(x_dict) # dict values converted to integer
w_dict = {**x_dict, **z_dict}
print(w_dict) # merge of first 3 items with values as integer and the rest of the dict intact
w_dict is the result you are looking for.
Let's say your dict stored in "book_data" variable.
What means first 3 keys?
If you have static keys, you can set manually for it:
for key in ['id', 'Book', 'Member']:
book_data[key] = int(book_data[key])
If you have mutable dictionary, you may get it with it:
for key, val in list(book_data.items())[:3]:
book_data[key] = int(val)
method items help you avoid iterate over values.

Scala two varying size list concatenate based on condition

I'm new to scala and trying to concatenate two varying size list based on condition,
Below are the lists,
val check1:String = "NULL||BLANK||LENGTH"
val check2:String = "LENGTH||DUPLICATE"
val check3:String = "NUMERIC"
val checkLists = List(check1,check2,check3)
checkLists: List[String] = List(NULL||BLANK||LENGTH, LENGTH||DUPLICATE, NUMERIC)
val condList = List(">=2","<7")
I'm trying to concatenate checkLists & condList based on condition and create new list, whenever List contains String "LENGTH" it should concatenated with condList like below
List(NULL||BLANK||LENGTH~>=2, LENGTH~<7||DUPLICATE, NUMERIC)
I can able to use zip, foreach and case to concatenate of two equal size lists but here I'm facing trouble with different size lists.
Using zipAll will give the answer you are looking for:
checkLists.zipAll(condList, "", "").map {
case (check, cond) => check.replaceAll("LENGTH", "LENGTH~" + cond)
}
List(NULL||BLANK||LENGTH~>=2, LENGTH~<7||DUPLICATE, NUMERIC)
The missing element of condList is given as "", but a different default condition could be used if required.
Note that if the second LENGTH string is in the third element of checkLists rather than the second element, it will not get any condition. This may or may not be what is required.

How to convert a list of strings into a dict object with kwarg as the keys?

I have seen similar questions. This one is the most similar that I've found:
Python converting a list into a dict with a value of 1 for each key
The difference is that I need the dict keys to be unique and ordered keyword arguments.
I am trying to feed the list of links I've generated through a scraper into a request command. I understand the request.get() function only takes a URL string or kwarg parameters - hence my need to pair the list of links with keyword arguments that are ordered.
terms = (input(str('type boolean HERE -->')))
zipcity = (input(str('type location HERE -->')))
search = driver.find_element_by_id('keywordsearch')
search.click()
search.send_keys('terms')
location = driver.find_element_by_id('WHERE')
location.click()
location.send_keys('zipcity')
clickSearch = driver.find_element_by_css_selector('#buttonsearch-button')
clickSearch.click()
time.sleep(5)
cv = []
cvDict = {}
bbb = driver.find_elements_by_class_name('user-name')
for plink in bbb:
cv.append(plink.find_element_by_css_selector('a').get_attribute('href'))
cvDict = {x: 1 for x in cv}
print(cvDict)
SOLVED: (for now). Somehow figured it out myself. That literally never happens. Lucky day I guess!
cvDict = {'one': cv[:1],
'tw': cv[:2],
'thr': cv[:3],
'fou': cv[:4],
'fiv': cv[:5],
'six': cv[:6],
'sev': cv[:7],
'eig': cv[:8],
'nin': cv[:9],
'ten': cv[:10],
'ele': cv[:11],
'twe': cv[:12],
'thi': cv[:13],
'fourteen': cv[:14],
'fifteen': cv[:15],
'sixteen': cv[:16],
'seventeen': cv[:17],
'eighteen': cv[:18],
'nineteen': cv[:19],
'twent': cv[:20],
}

how to convert all the values in a list into keys of a Dictionary in Py2.7

I've below lists,
lists=[ ['arya','egg','milk','butter','bread'],
['Jon','butter','pastrie','yogurt','beer'],
['bran','beer','milk','banana','apples'],]
Each list has values in which the first value is the name of a person and rest of all are some food items. I've a task where I've to create a dictionary with these food items as keys and the person as a value as shown below
dict = { 'egg' : set(['arya']),
'milk': set(['arya','bran']),
'butter' : set(['arya','jon']),
'bread' : set(['arya']),
'pastrie' : set(['jon']),
'milk' : set(['bran'])
} # few keys omitted
This is what I did and stopped, dont know how to proceed further,
food,person = [],[]
for i in lists:
food.append(i[1:])
person.append(i[0])
I was able to seperate the first value of each list and append it to a list
and same with food.
Dont know how to proceed further.
started learning python, Any input is highly helpful. kindly share one or two lines of explanation to enlighten this newbie !
Thank you so much.
Using dictionary method setdefault is helpful here.
You of course don't nee to set the slices to a variable, but it makes it easier to read.
d = {}
for l in lists:
name = l[0]
items = l[1:]
for item in items:
d.setdefault(item, set()).add(name)
Use a collections.defaultdict:
lists = [['arya', 'egg', 'milk', 'butter', 'bread'],
['Jon', 'butter', 'pastrie', 'yogurt', 'beer'],
['bran', 'beer', 'milk', 'banana', 'apples']]
from collections import defaultdict
d = defaultdict(set)
for sub in lists:
for v in sub[1:]:
d[v].add(sub[0])
print(d)
Output:
defaultdict(<class 'set'>,
{'bread': {'arya'}, 'yogurt': {'Jon'}, 'beer': {'Jon', 'bran'},
'banana': {'bran'}, 'butter': {'Jon', 'arya'}, 'milk': {'arya',
'bran'}, 'pastrie': {'Jon'}, 'egg': {'arya'}, 'apples': {'bran'}})
For python3 the syntax is a little nicer:
from collections import defaultdict
d = defaultdict(set)
for name, *rest in lists:
for v in rest:
d[v].add(name)

parameters aren't being read in py2neo

I'm trying to query based on node number and return a list of properties. The following cypher query works in the neo4j browser but when I try to pass the same cypher query via py2neo I get:
"Expected a property container or number here, but got:91"
where "91" is the node number I'm querying on.
an excerpt from my code:
def neighbor_finder(a):
try:
graph_db = neo4j.GraphDatabaseService(url)
query = neo4j.CypherQuery(graph_db,
"""CYPHER 2.0
MATCH (n)-[r]-(m)
WHERE ID(n) = {t}
WITH collect (Distinct m.size) as sizes, collect (Distinct m.weight) as weights, collect (Distinct m.color) as colors, collect (distinct n.label) as node_
RETURN sizes, weights, colors, node_
""")
result = query.execute(t=a)
for r in result:
column = [str(item) for item in r.columns]
value = [str(item) for item in r.values]
db_dict={k: v for k, v in zip(column, value)}
for x, y in db_dict.items():
print x, y
except Exception as e:
print e
Can you provide details of the type and value of the a argument that is passed into this function? Without it I cannot see what py2neo is passing into the query parameters.
argument "a" isn't being read because it needs to be declared as an integer, cypher/py2neo are currently reading it as a string.