0

My goal is to get a list of Objects named recursively dynamically. This is the code I tried. I want the object_list to be [Object_0, Object_1, Object_2, Object_3, Object_4]

object_list = []

class Object(object):  
    size = ""
    price = ""

def create_object_list(object_list):   
    for num in range(5):
        Object_%s = Object() %num  
        object_list.append(Object_%s)
    return object_list

This is the error:

Object_%s = Object() %num
SyntaxError: can't assign to operator
tmthydvnprt
  • 10,398
  • 8
  • 52
  • 72
Blender User
  • 25
  • 1
  • 4
  • I think you mean dynamically, not recursively. http://stackoverflow.com/questions/5036700/how-can-you-dynamically-create-variables-in-python-via-a-while-loop – dting Apr 25 '15 at 11:29
  • 1
    Perhaps you'd better tell us what is it you're trying to achieve. We could help you much better that way. – Elektito Apr 25 '15 at 11:42
  • possible duplicate of [Python - Use a variable as a list name](http://stackoverflow.com/questions/13324465/python-use-a-variable-as-a-list-name) – Fiver Apr 25 '15 at 15:13

6 Answers6

0

Having seen the comments on the page, the real answer is just use a list and don't try and give the objects names to denote their place in the list. What you are trying to do is an antipattern. You don't need to set the "name" of the object as if you want to access object_n you can get it via objects[n]. Additionally you can keep things simple use a dict or a namedtuple instead of your custom class.

from random import random

objects = []

for i in range(5):
    obj = {'size': random(), 'price': random()}
    objects.append(obj)

print(objects[0])
print(objects[3]['size'])
print(objects[1]['price'])

For the specific error in the question:

You can't use % in a variable name as it is an operator. See here for what you can use in a name:

https://docs.python.org/2/reference/lexical_analysis.html#identifiers

>>> variable_name = 1
>>> variable_%name = 2
  File "<input>", line 1
SyntaxError: can't assign to operator
>>>

There are several other problems in the code in your question that will probably bite you:

  • Your Object has class variables and not instance variables.
  • You are somehow mixing string and integers.
  • You are not actually using recursion in your code (this is in most cases a good thing though).
YXD
  • 31,741
  • 15
  • 75
  • 115
  • What I'm trying to do is a kind of c++ array of structures(An structure on each cell). I thought this would be the way to do it in python. – Blender User Apr 25 '15 at 11:39
  • You almost certainly want a `list` of `dicts` or a `dict` of `lists` or some other combination of built-in data structures. I suggest having a read of https://docs.python.org/2/tutorial/datastructures.html Most Python code ends up looking extremely simple and boring, especially compared to C++ :) – YXD Apr 25 '15 at 11:44
  • @BlenderUser check the ctypes module, and the Structure class... Is this what you want to do? – chapelo Apr 25 '15 at 14:26
0

Did you mean:

exec("Object_%s = Object()" %num)
exec("object_list.append(Object_%s)" %num)

Because otherwise it looks like you are trying to format live lines of code and not strings. That's the obvious error in your code - but otherwise I must agree with all others - if you don't have a good reason for creating variables - just use a dic.

alex.feigin
  • 386
  • 1
  • 11
0

I think you want an object_dict:

object_dict = {}

class Object(object):
    size = ""
    price = ""

def create_object_list(object_dict):
    for num in range(5):
        object_dict["Object_{}".format(num)] = Object()
    return object_dict

If you need order for some reason use a collections.OrderedDict:

from collections import OrderedDict
object_dict = OrderedDict()

which will keep the order the object are created:

OrderedDict([('Object_0', <__main__.Object object at 0x7f05d4044390>), ('Object_1', <__main__.Object object at 0x7f05d3fd3710>), ('Object_2', <__main__.Object object at 0x7f05d3fd36d8>), ('Object_3', <__main__.Object object at 0x7f05d3fd3a90>), ('Object_4', <__main__.Object object at 0x7f05d273a278>)])

You can access each object by key:

print(object_dict["Object_0"])
<__main__.Object object at 0x7f05d4044390>
Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
0

You are trying to dynamically create variable names which is not possible. The % operator only works for strings not identifiers. You probably want to use a list here of strings.

If you really want to create new variables dynamically you can use the locals() built-in function which contains a dictionary of local variables. You can for example use locals()['object_%d' % num] = Object(). The globals() function can be used if you want to create global variables.

Notice that even if you do this, you won't get a list of variable names when you print the list; you'll get a list of values.

Elektito
  • 3,863
  • 8
  • 42
  • 72
0

Yet another way to do this:

class Object(object):
    def __init__(self, inst_id):
        self.name = "Object_%d" % inst_id 
        self.size = ""
        self.price = ""

def create_object_list(object_list):
    for num in range(6):
        object_list.append(Object(num))
    return object_list         


for x in create_object_list(object_list):
    print x.name

Object_0
Object_1
Object_2
Object_3
Object_4
Object_5
0

Say you have these five variables:

a = (1,2,3)
e = "a string"
i = 1.56
o = {'size':'small', 'price':'low'}
u = None

and a list grouping them:

them = [a,e,i,o,u]

You could have created this list dinamically this way:

same = [eval(_) for _ in 'aeiou']
print(same)
# [(1, 2, 3), 'a string', 1.56, {'price': 'low', 'size': 'small'}, None]

So, the list of variables you need to create can be done the same way:

object_list = [eval('Object_'+str(n)) for n in range(5)]

If the objects already exsist, you can use the variables inside your list, but to create the variables themselves dinamically, you could do:

for _ in ('Object_'+str(n)+'=None' for n in range(5)): # or '=...' any appropriate value
    exec(_)                                            # it could be a call to your Object()

print(objcet_list)
# [None, None, None, None, None] 
chapelo
  • 2,519
  • 13
  • 19