Get Attributes python - python

class A(object):
a = 1
b = 0
c = None
d = None
a_obj=A()
a_list = ['a', 'b', 'c', 'd']
attrs_present = filter(lambda x: getattr(a_obj, x), a_list)
I want both a and b attributes, here 0 is a valid value. I don't want to use comparison==0
is there a way to get those?
Any help will be appriciated, Thanks.

If you want to exclude c, d (Nones), use is None or is not None:
attrs_present = filter(lambda x: getattr(a_obj, x, None) is not None, a_list)
# NOTE: Added the third argument `None`
# to prevent `AttributeError` in case of missing attribute
# (for example, a_list = ['a', 'e'])
If you want to include c, d, use hasattr:
attrs_present = filter(lambda x: hasattr(a_obj, x), a_list)

Related

Return the name of a list if it contain the needed value (Python)

am trying to get the name of a list (type list) if it contain the needed value:
def f(Value):
a = ['a','b','c']
b = ['d','e','f']
d = ['g','h','i']
c = ['j','k','l']
w = next(n for n,v in filter(lambda t: isinstance(t[1],list), locals().items()) if value in v)
return(w)
f()
well this code will return the name of the list but type string so i will be not able to use it later. thank you in advance
You got several errors in your code - if you want the list, then return it and not it's name:
def f(value): # capitalization not correct
a = ['a','b','c']
b = ['d','e','f']
d = ['g','h','i']
c = ['j','k','l']
# set w to v not n - n is the local name, v is the value
w = next(v for n,v in filter(lambda t: isinstance(t[1],list),
locals().items()) if value in v)
return w
# needs to be called with parameter
what_list = f("h")
print( what_list )
Output:
['g', 'h', 'i']
I don't see the point why using locals().items() in this minimal example, you could do
for li in [a,b,c,d]: # simply add more lists if needed, no need to inspect locals
if value in li:
return li
instead.

Finding the minimum value for different variables

If i am doing some math functions for different variables for example:
a = x - y
b = x**2 - y**2
c = (x-y)**2
d = x + y
How can i find the minimum value out of all the variables. For example:
a = 4
b = 7
c = 3
d = 10
So the minimum value is 3 for c. How can i let my program do this.
What have i thought so far:
make a list
append a,b,c,d in the list
sort the list
print list[0] as it will be the smallest value.
The problem is if i append a,b,c,d to a list i have to do something like:
lst.append((a,b,c,d))
This makes the list to be -
[(4,7,3,10)]
making all the values relating to one index only ( lst[0] )
If possible is there any substitute to do this or any way possible as to how can i find the minimum!
LNG - PYTHON
Thank you
You can find the index of the smallest item like this
>>> L = [4,7,3,10]
>>> min(range(len(L)), key=L.__getitem__)
2
Now you know the index, you can get the actual item too. eg: L[2]
Another way which finds the answer in the form(index, item)
>>> min(enumerate(L), key=lambda x:x[1])
(2, 3)
I think you may be going the wrong way to solving your problem, but it's possible to pull values of variable from the local namespace if you know their names. eg.
>>> a = 4
>>> b = 7
>>> c = 3
>>> d = 10
>>> min(enumerate(['a', 'b', 'c', 'd']), key=lambda x, ns=locals(): ns[x[1]])
(2, 'c')
a better way is to use a dict, so you are not filling your working namespace with these "junk" variables
>>> D = {}
>>> D['a'] = 4
>>> D['b'] = 7
>>> D['c'] = 3
>>> D['d'] = 10
>>> min(D, key=D.get)
'c'
>>> min(D.items(), key=lambda x:x[1])
('c', 3)
You can see that when the correct data structure is used, the amount of code required is much less.
If you store the numbers in an list you can use a reduce having a O(n) complexity due the list is not sorted.
numbers = [999, 1111, 222, -1111]
minimum = reduce(lambda mn, candidate: candidate if candidate < mn else mn, numbers[1:], numbers[0])
pack as dictionary, find min value and then find keys that have matching values (possibly more than one minimum)
D = dict(a = 4, b = 7, c = 3, d = 10)
min_val = min(D.values())
for k,v in D.items():
if v == min_val: print(k)
The buiit-in function min will do the trick. In your example, min(a,b,c,d) will yield 3.

Is it posible to return on the line with exception?

I have a code which looks like this:
try:
a = form['a']
except KeyError:
pass
try:
b = form['b']
except KeyError:
pass
try:
c = form['c']
except KeyError:
pass
try:
d = form['d']
except KeyError:
pass
Is it posible to do something like this:
try:
a = form['a']
b = form['b']
c = form['c']
d = form['d']
except KeyError:
somekeyword
So if there is no key 'a' in form still working and try to find key 'b' and so on
UPD:
Sorry, my bad. I need to preserve all values not just one of them.
So I need the keyword or something like that that will help me continue try block even after exception raises.
If form is a dictionary you may also use .get(key, [default]) syntax:
>>> form = {'d':5}
>>> form.get('a', form.get('b', form.get('c', form['d'])))
5
You can make the function calls lazy by using some iterators:
>>> from itertools import dropwhile
>>> it = (form.get(k) for k in ['a', 'b', 'c', 'd'])
>>> next(dropwhile(lambda val: val is None, it))
5
edit: if you need all four:
>>> a, b, c, d = map(form.get, ['a', 'b', 'c', 'd'])
>>> a, b, c, d
(None, None, None, 5)
You could simply do this, assuming form supports full dict semantics, and that None is actually a valid value of the form:
sentinel = object()
user = sentinel
for key in "abcd":
user = form.get(key, user)
if user is sentinel: # I don't know if None is a va
whatever-you-mean-with-somekeyword

Is it possible to assign variables within the assignment of another variable?

I have two questions:
1) I want to write a statement like: superVar = [subVar1 = 'a', subVar2 = 'b']
After this statement, I want:
superVar = ['a', 'b']
subVar1 = 'a'
subVar2 = 'b'
Is this somehow achievable in python?
2) I want to do the following inside a class's init function:
self.superVar = [v1 = 'a', v2 = 'b']
After this statement, I want:
self.superVar = ['a', 'b']
self.superVar.v1 = 'a'
self.superVar.v2 = 'b'
i.e. have 'superVar' be part of the name of the other variables.
As you might have guessed, what I really want to do is (2) above. (1) is just the first step and I would be happy even with that, if (2) is not possible.
Thanks a lot!
Gaurav
>>> from collections import namedtuple
>>> T = namedtuple('supervar', ['v1', 'v2'])
>>> superVar = T('a', 'b')
>>> superVar.v1
'a'
>>> superVar.v2
'b'
Do you mean a dictionary?
superVar = {'subVar1': 'a', 'subVar2': 'b'}
superVar['subVar1']
# 'a'
superVar['subVar2']
# 'b'
In a class:
class Foo(object):
def __init__(self, a, b):
self.superVar = {'subVar1' : a, 'subVar2' : b}
bar = Foo('one', 'two')
bar.superVar.values()
# ['one', 'two']
If you want to keep order, you can use an ordered dictionary from the collections module.
Why not create a dictionary for your subVars and make superVar a list of values from the subVar dictionary?
d = {'subVar1': 'value1', 'subVar2': 'value2'}
superVar = d.values()
In Python, assignments are statements, not expressions. You can't chain together statements. So (1) is impossible.
However, you can use keyword arguments in the __init__ method of a class to get the behavior in (2):
>>> class Test:
def __init__(self, **kwargs):
print "the keyword arguments are", kwargs #kwargs is a dictionary
for x in kwargs:
setattr(self, x, kwargs[x]) #adds an attribute from kwargs to self
>>> t = Test(var1=1234,var2='hello',var3=45.234)
the keyword arguments are {'var1': 1234, 'var3': 45.234, 'var2': 'hello'}
>>> t.var1
1234
>>> t.var2
'hello'
>>> t.var3
45.234
>>>
This is basically the same as Jeremy Bentham's answer,
class T:
def __init__(self):
self.SuperVar = {'v1':'a', 'v2':'b'}
print self.SuperVar.v1
print self.SuperVar.v2
def __setattr__(self, k, v):
class SuperVar:
def __setattr__(self, k, v):
self.__dict__[k] = v
if k == "SuperVar":
self.__dict__["SuperVar"] = SuperVar()
for k in v:
self.__dict__["SuperVar"].__setattr__(k, v[k])
else:
self.__dict__[k] = v
t = T()

Python Dictionary of Dictionary with condition

I am working on a function. If "source" is found in "d" then it will be added to it's value of dictionary object, otherwise it will be added. For example in this case. "a" is added twice but "b" is added once.
I would like to get output as below(last line)
Thank you.
def adder(source,dest,weight):
""""""
if __name__ == "__main__":
d = {} #dictionary
adder('a','b',1)
adder('a','f',4)
adder('b','c',1)
adder('f','g',3)
print d
{'a':{'b':1,'f':4}, 'b':{'c':1}, 'f':{'g':3},g:{},c:{}} #<----final o/p needed
A dictionary of dictionaries is just a dictionary of tuples. You could implement adder like this:
#The dictionary we will be adding to
d = {}
def adder(source, dest, weight):
d[(source, dest)] = weight
The high brow reason for this is that in any category with products, Hom(C, Hom(B, A)) is naturally isomorphic to Hom(C x B, A). Or in a functional language,
f : C -> (B -> A)
Is the same as:
f : C x B -> A
And coincidentally, it is also why (A^B)^C = A^(B * C).
The following implementation should do so:
def adder(dict, source, dest, weight):
if not source in dict:
dict[source] = {}
if not dest in dict:
dict[dest] = {}
dict[source][dest] = weight
Please note that I added dict as first argument to your method.
You can just use a simple if condition:
In [9]: def adder(d,source,dest,weight):
...: if source in d:
...: d[source][dest] = weight
...: else:
...: d[source] = {dest: weight}
...:
In [10]: d={}
In [11]: adder(d, 'a', 'b', 1)
In [12]: adder(d, 'a', 'f', 4)
In [13]: adder(d, 'b', 'c', 1)
In [14]: d
Out[14]: {'a': {'b': 1, 'f': 4}, 'b': {'c': 1}}

Categories