Function call inside a loop python - python

I do have following problem -
dict1 = {'abc': {'x': 2, 'y': 3, 'z': 4}, 'mno': {'p': 3, 'q':4, 'r':5}}
def refine():
def calc(a_dict):
if some_condition :
return x ={'a':1}
else:
return None
for k, v in dict1:
return calc(v)
Now when I am iterating this function call inside a for loop , I get either None or a. The function call is such that I can get maximum of one a .
Sample Output-
None
None
{'a':1}
None
What I want calc function to return None in case all the values after the loop gives None or x in case any of the values after loop gives x .How can this be achieved ? Thanks in advance.
Edit -
What if I store the results in a list and want to check if the list has something else than None and if True return it.

If I did get the question, you may store results of conditions applied on a dictionary and then check with all quantifier function:
def calc(a_dict):
results = (some_condition(k,v) for k,v in a_dict.iteritems())
if all(res == None for res in results):
return None
elif all(res == <something> for res in results):
return {'a':1}
else:
return <something different>

u can use any() . any check for the condition if any one value is true. it return x . if all values fail it goes to else
if any(somecondition):
return x
else:
return None

Related

mapping dictionary value to list and return original value if key doesn't exist

I have a list seems like this :
a = ['jokowi','jokowidodo','ir h jokowidodo','teungku']
and a dictionary like this
{'jokowi': 'jokowi', 'jokowidodo': 'jokowi', 'ir h jokowidodo': 'jokowi'}
and make a mapping using this code:
list(map(data_dict.get,listakoh))
and then it returns:
['jokowi', 'jokowi', 'jokowi', None]
the question is how can I replace None in the result with the original value of my previous list, so None in the result must be 'teungku'
You can use a second argument to get as a default value:
list(map(lambda x: data_dict.get(x, x), a))
You can simply define your own function and map that.
a = ['jokowi','jokowidodo','ir h jokowidodo','teungku']
d = {'jokowi': 'jokowi', 'jokowidodo': 'jokowi', 'ir h jokowidodo': 'jokowi'}
def f(k):
global d
try:
return d[k]
except KeyError:
return k
r = list(map(f, a))
print(r)
['jokowi', 'jokowi', 'jokowi', 'teungku']
You can easily compare the mapped list with the original list and replace the None values with those from the actual list.
>>> new_list = list(map(data_dict.get,listakoh))
>>> for index, element in enumerate(new_list):
if element == None:
new_list[index]=a[index]
>>> print(new_list)
['jokowi', 'jokowi', 'jokowi', 'teungku']

What's the output of 'd = {0, 1, 2} for x in d: print(d.add(x)) .And why?

The Python code is:
d = {0, 1, 2}
for x in d:
print(d.add(x))
What is the output, and why?
The output is just
None
None
None
This is because d.add(x) adds x to the set and returns None.
Let's understand this step by step
(1) d is a set of elements{0,1,2}
(2)Set is a data structure which has only unique values
Loop:
(3)for x in d:
print(d.add(x))
this will take each element from the set and add it to self (d.add(x))
AND it returns nothing.
(4)You will get the output three times None because the loop will run three times
As it is a set adding elements to itself will return the original set(It will discard the duplicate entries)

If key contain substring in Python

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

Get Dictionary value Python

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.

Python convert string to array assignment

In my application I am receiving a string 'abc[0]=123'
I want to convert this string to an array of items. I have tried eval() it didnt work for me. I know the array name abc but the number of items will be different in each time.
I can split the string, get array index and do. But I would like to know if there is any direct way to convert this string as an array insert.
I would greately appreciate any suggestion.
are you looking for something like
In [36]: s = "abc[0]=123"
In [37]: vars()[s[:3]] = []
In [38]: vars()[s[:3]].append(eval(s[s.find('=') + 1:]))
In [39]: abc
Out[39]: [123]
But this is not a good way to create a variable
Here's a function for parsing urls according to php rules (i.e. using square brackets to create arrays or nested structures):
import urlparse, re
def parse_qs_as_php(qs):
def sint(x):
try:
return int(x)
except ValueError:
return x
def nested(rest, base, val):
curr, rest = base, re.findall(r'\[(.*?)\]', rest)
while rest:
curr = curr.setdefault(
sint(rest.pop(0) or len(curr)),
{} if rest else val)
return base
def dtol(d):
if not hasattr(d, 'items'):
return d
if sorted(d) == range(len(d)):
return [d[x] for x in range(len(d))]
return {k:dtol(v) for k, v in d.items()}
r = {}
for key, val in urlparse.parse_qsl(qs):
id, rest = re.match(r'^(\w+)(.*)$', key).groups()
r[id] = nested(rest, r.get(id, {}), val) if rest else val
return dtol(r)
Example:
qs = 'one=1&abc[0]=123&abc[1]=345&foo[bar][baz]=555'
print parse_qs_as_php(qs)
# {'abc': ['123', '345'], 'foo': {'bar': {'baz': '555'}}, 'one': '1'}
Your other application is doing it wrong. It should not be specifying index values in the parameter keys. The correct way to specify multiple values for a single key in a GET is to simply repeat the key:
http://my_url?abc=123&abc=456
The Python server side should correctly resolve this into a dictionary-like object: you don't say what framework you're running, but for instance Django uses a QueryDict which you can then access using request.GET.getlist('abc') which will return ['123', '456']. Other frameworks will be similar.

Categories