How to create a series of variables automatically? - python-2.7

How can I create a series of variables automatically with python?
Like this:
tmp1=1;
tmp2=1;
tmp3=1;
tmp4=1;
tmp5=1;

Look at this SO question. you have several ways to do that:
Use dict or collection instead
Using globals
Using the exec() method
About the first solution (dict or collection) - is not actually what you asked for, which is to create a variable in the global scope.. but I would go with that anytime. I don't see really any reason why I'd need to create variables dynamically instead of using some datatype.
I would say that using both globals and exec() method for this is a bad practice.

Store them in a dictionary
d = {}
value = ['a','b','c']
for key in range(1, 3):
d[key]= value[key]
print d
> {0:'a',1:'b',2:'c'}
print d[0]
> 'a'
(Comments? I am new to python too!)

I think I have got an answer somewhere:
for i in range(100):
locals()['tmp%d'%i]=1
or:
>>> for i in range(1, 10):
... exec 'tmp' + str(i) + '=1'
I don't know if I have a ambiguity describe, the above two is exactly I want.

Related

Pass capitalised variables to django settings.configure() [duplicate]

Does python have the ability to create dynamic keywords?
For example:
qset.filter(min_price__usd__range=(min_price, max_price))
I want to be able to change the usd part based on a selected currency.
Yes, It does. Use **kwargs in a function definition.
Example:
def f(**kwargs):
print kwargs.keys()
f(a=2, b="b") # -> ['a', 'b']
f(**{'d'+'e': 1}) # -> ['de']
But why do you need that?
If I understand what you're asking correctly,
qset.filter(**{
'min_price_' + selected_currency + '_range' :
(min_price, max_price)})
does what you need.
You can easily do this by declaring your function like this:
def filter(**kwargs):
your function will now be passed a dictionary called kwargs that contains the keywords and values passed to your function. Note that, syntactically, the word kwargs is meaningless; the ** is what causes the dynamic keyword behavior.
You can also do the reverse. If you are calling a function, and you have a dictionary that corresponds to the arguments, you can do
someFunction(**theDictionary)
There is also the lesser used *foo variant, which causes you to receive an array of arguments. This is similar to normal C vararg arrays.
Yes, sort of.
In your filter method you can declare a wildcard variable that collects all the unknown keyword arguments. Your method might look like this:
def filter(self, **kwargs):
for key,value in kwargs:
if key.startswith('min_price__') and key.endswith('__range'):
currency = key.replace('min_price__', '').replace('__range','')
rate = self.current_conversion_rates[currency]
self.setCurrencyRange(value[0]*rate, value[1]*rate)

Incrementing specific parameter in all objects in the QuerySet

I am trying to increment the same parameter in all objects in the query set.
What I am doing right now:
q = SomeModel.objects.all()
for object in q:
object.my_parameter += 1
object.save()
I have wondered if it could be achieved in a simpler way, e.g. using update() function. To put it simply I would like to do something like this:
SomeModel.objects.all().update(my_parameter += 1)
I just can't believe that there is no shortcut for what I want to do.
Edit:
Resolved! Thank you!
You can do this by F() expressions
from django.db.models import F
SomeModel.objects.all().update(my_parameter=F('my_parameter') + 1)
Further reading https://docs.djangoproject.com/en/2.0/ref/models/expressions/#f-expressions
Certainly you could do it in a single bulk update. Check this out: Updating multiple objects at once.
I prefer to use the F expression too:
from django.db.models import F
SomeModel.objects.all().update(my_parameter =F('my_parameter') + 1)

Call a key from a dictionary without knowing its name

Is there a way to call a key without directly calling it? For example, if I have this code and I want to call "Voltage_active(V)" without typing "Values['Voltage_active']" is there a way to do that?
Values = {"Voltage_active(V)" : 10, }
I wanted to create a new variable like below, but that code does not work
functional_voltage = Values[key]
You show a dictionary that has only one entry. In that case, observe that we can obtain its value via:
>>> Values = {"Voltage_active(V)" : 10, }
>>> list(Values.values())[0]
10
By using list, we have made this compatible with Python3 as well as Python2.

Python: Cleaner ways to initialize

Or maybe I should say, ways to skip having to initialize at all.
I really hate that every time I want to do a simple count variable, I have to say, "hey python, this variable starts at 0." I want to be able to say count+=1and have it instantly know to start from 0 at the first iteration of the loop. Maybe there's some sort of function I can design to accomodate this? count(1) that adds 1 to a self-created internal count variable that sticks around between iterations of the loop.
I have the same dislike for editing strings/lists into a new string/list.
(Initializing new_string=""/new_list=[] before the loop).
I think list comprehensions may work for some lists.
Does anyone have some pointers for how to solve this problem? I am fairly new, I've only been programming off and on for half a year.
Disclaimer: I do not think that this will make initialization any cleaner. Also, in case you have a typo in some uses of your counter variable, you will not get a NameError but instead it will just silently create and increment a second counter. Remember the Zen of Python:
Explicit is better than implicit.
Having said that, you could create a special class that will automatically add missing attributes and use this class to create and auto-initialize all sorts of counters:
class Counter:
def __init__(self, default_func=int):
self.default = default_func
def __getattr__(self, name):
if name not in self.__dict__:
self.__dict__[name] = self.default()
return self.__dict__[name]
Now you can create a single instance of that class to create an arbitrary number of counters of the same type. Example usage:
>>> c = Counter()
>>> c.foo
0
>>> c.bar += 1
>>> c.bar += 2
>>> c.bar
3
>>> l = Counter(list)
>>> l.blub += [1,2,3]
>>> l.blub
[1, 2, 3]
In fact, this is similar to what collections.defaultdict does, except that you can use dot-notation for accessing the counters, i.e. c.foo instead of c['foo']. Come to think of it, you could even extend defaultdict, making the whole thing much simpler:
class Counter(collections.defaultdict):
def __getattr__(self, name):
return self[name]
If you are using a counter in a for loop you can use enumerate:
for counter, list_index in enumerate(list):
the counter is the first variable in the statement and 1 is added to it per iteration of the loop, the next variable is the value of that iteration in the list. I hope this answers your first question as for your second, the following code might help
list_a = ["this", "is"]
list_b = ["a", "test"]
list_a += list_b
print(list_a)
["this", "is", "a", "test"]
The += works for strings as well because they are essentially lists aw well. Hope this helps!

Can you translate this debugging macro from C++ to python?

I use this very helpful macro when developing in C++:
#define DD(a) std::cout << #a " = [ " << a << " ]" << std::endl;std::cout.flush();
Could you help me implement the same idea in python? I don't know how the #a could be implemented with a python function...
As #Andrea Spadaccini and #adirau point out, it is not possible to reliably map values back to Python variable names. You could trawl through all namespaces looking for some variable name that references the given value, but that would be fighting the system and liable to return the wrong variable name.
Much easier it is to just pass the variable name:
import inspect
def pv(name):
frame,filename,line_number,function_name,lines,index=inspect.getouterframes(
inspect.currentframe())[1]
# print(frame,filename,line_number,function_name,lines,index)
val=eval(name,frame.f_globals,frame.f_locals)
print('{0}: {1}'.format(name, val))
a=5
pv('a')
yields:
a: 5
You could inspect the stack trace and "parse" it. Since you know the name of your function (dd in this case) it becomes fairly easy to find the call and extract the name of the variable.
import inspect
import re
def dd(value):
calling_frame_record = inspect.stack()[1]
frame = inspect.getframeinfo(calling_frame_record[0])
m = re.search( "dd\((.+)\)", frame.code_context[0])
if m:
print "{0} = {1}".format(m.group(1), value)
def test():
a = 4
dd(a)
test()
Output
a = 4
I think that this cannot be done.
The debugging macro that you posted works because it is expanded before compilation, during pre-processing, when you know the variable name. It is like you write all those couts by yourself.
Python does not have a pre-processor (AFAIK), there are external tools that do a similar thing (pyp and others), but you can not define a macro with the standard language.
So you should do your trick at run-time. Well, at run-time you don't know the "name" of the variable because the variable is just a reference to an object, when you call a method you call it on the object, not on the "variable". There can be many variables that point to that object, how does the object know which variable was used to call the method?
You can't get a variable (well, object)'s name in python. But you can pass the object's name to get its value (kinda the opposite of what you do with that macro)
>>> a=4
>>> locals()['a']
4
EDIT: a detailed explanation may be found here
import sys
def DD(expr):
frame = sys._getframe(1)
print '%s = %s' % (expr, repr(eval(expr, frame.f_globals, frame.f_locals)))
GLOBAL_VAR = 10
def test():
local_var = 20
DD('GLOBAL_VAR + local_var')
>>> test()
GLOBAL_VAR + local_var = 30
The Rod solution is perfectly usable.
It could be even extended to handle many vars.
But you can get close to that with much less magic:
def dd(**kwargs):
print ", ".join(str(k) + "=" + str(v) for k, v in kwargs.iteritems())
a = 1
dd(a=a,b=3)
output:
a=1, b=3