Elegant way of loading series of objects into a list - python

I have a need to iterate over bunch of objects(30+ Objects are for 30+ buttons). Therefore I have a list looks like this,
myObjList = [my.obj.obj1, my.obj.obj2, my.obj.obj3, ....... ]
What would be the most elegant way to load a list with these objects?

Since you're looking for flexible dot access, you're probably best off with getattr in a list comprehension:
myObjList = [getattr(my.obj, 'obj'+str(i)) for i in range(n)]
where n is the number of obj<i> you need to get from my.obj.

Related

Fastest way to calculate new list from empty list in python

I want to perform calculations on a list and assign this to a second list, but I want to do this in the most efficient way possible as I'll be using a lot of data. What is the best way to do this? My current version uses append:
f=time_series_data
output=[]
for i, f in enumerate(time_series_data):
if f > x:
output.append(calculation with f)
etc etc
should I use append or declare the output list as a list of zeros at the beginning?
Appending the values is not slower compared to other ways possible to accomplish this.
The code looks fine and creating a list of zeroes would not help any further. Although it can create problems as you might not know how many values will pass the condition f > x.
Since you wrote etc etc I am not sure how long or what operations you need to do there. If possible try using list comprehension. That would be a little faster.
You can have a look at below article which compared the speed for list creation using 3 methods, viz, list comprehension, append, pre-initialization.
https://levelup.gitconnected.com/faster-lists-in-python-4c4287502f0a

Sorting a list with entries in string format

In Python, have a list with items (strings) that look like this:
"1.120e+03 8.140e+02 3.234e+01 1.450e+00 1.623e+01 7.940e+02 3.113e+01 1.580e+00 1.463e+01"
I want to sort this list based on the size of the first number in each string (smallest to largest). In the above case that would be "1.120e+03".
I can think of a couple of ways to do it, but they involve creating new lists and a couple of for loops which I guess isn't so efficient (or elegant). Is there a quick way to do this?
If you are sorting it more than once, I suggest you create your Class for the data and override methods for comparing such as __lt__.

Variables/Functions in Python Dictionaries

I'm not sure whether this kind of functionality exists or not or how is best to go about this. I am wanting to create a general problem solver where I can define the predicates, operations and such before solving rather than coding directly. So far I have been storing functions as part of a dictionary. The only way that it seems possible to do this with a dictionary is to create it with every potential combination imaginable.
For example, previously it was this:
self.Operators = {"STACK": self.stack, "UNSTACK": self.unstack,
"PICKUP": self.pickup, "PUTDOWN": self.putdown}
Where I would now like it to be something more like:
self.Operators = {("STACK", x, y): [[("clear", y), ("holding", x)], ["armempty", ("on", x, y)]]}
I know I am probably barking up the wrong tree with dictionaries here but this is the first time I've tried to do something like this and I have no idea what the appropriate/most Pythonesque way to manage this is?
I have solved this using the following (which is what I am going to go with):
self.Operators = {'PICKUP': [[['ontable', 'a'], ['armempty']], [['holding', 'a']]]}
The list that is then returned I parse using a list comprehension:
y = [w.replace("a", args[0]) for w in y]
For a list that has multiple variables, I will end up doing multiple list comprehensions by enumerating through characters.

How to grow a list to fit a given capacity in Python

I'm a Python newbie. I have a series of objects that need to be inserted at specific indices of a list, but they come out of order, so I can't just append them. How can I grow the list whenever necessary to avoid IndexErrors?
def set(index, item):
if len(nodes) <= index:
# Grow list to index+1
nodes[index] = item
I know you can create a list with an initial capacity via nodes = (index+1) * [None] but what's the usual way to grow it in place? The following doesn't seem efficient:
for _ in xrange(len(nodes), index+1):
nodes.append(None)
In addition, I suppose there's probably a class in the Standard Library that I should be using instead of built-in lists?
This is the best way to of doing it.
>>> lst.extend([None]*additional_size)
oops seems like I misunderstood your question at first. If you are asking how to expand the length of a list so you can insert something at an index larger than the current length of the list, then lst.extend([None]*(new_size - len(lst)) would probably be the way to go, as others have suggested. Of course, if you know in advance what the maximum index you will be needing is, it would make sense to create the list in advance and fill it with Nones.
For reference, I leave the original text: to insert something in the middle of the existing list, the usual way is not to worry about growing the list yourself. List objects come with an insert method that will let you insert an object at any point in the list. So instead of your set function, just use
lst.insert(item, index)
or you could do
lst[index:index] = item
which does the same thing. Python will take care of resizing the list for you.
There is not necessarily any class in the standard library that you should be using instead of list, especially if you need this sort of random-access insertion. However, there are some classes in the collections module which you should be aware of, since they can be useful for other situations (e.g. if you're always appending to one end of the list, and you don't know in advance how many items you need, deque would be appropriate).
Perhaps something like:
lst += [None] * additional_size
(you shouldn't call your list variable list, since it is also the name of the list constructor).

Parsing indeterminate amount of data into a python tuple

I have a config file that contains a list of strings. I need to read these strings in order and store them in memory and I'm going to be iterating over them many times when certain events take place. Since once they're read from the file I don't need to add or modify the list, a tuple seems like the most appropriate data structure.
However, I'm a little confused on the best way to first construct the tuple since it's immutable. Should I parse them into a list then put them in a tuple? Is that wasteful? Is there a way to get them into a tuple first without the overhead of copying/destroying the tuple every time I add a new element.
As you said, you're going to read the data gradually - so a tuple isn't a good idea after all, as it's immutable.
Is there a reason for not using a simple list for holding the strings?
Since your data is changing, I am not sure you need a tuple. A list should do fine.
Look at the following which should provide you further information. Assigning a tuple is much faster than assigning a list. But if you are trying to modify elements every now and then then creating a tuple may not make more sense.
Are tuples more efficient than lists in Python?
I wouldn't worry about the overhead of first creating a list and then a tuple from that list. My guess is that the overhead will turn out to be negligible if you measure it.
On the other hand, I would stick with the list and iterate over that instead of creating a tuple. Tuples should be used for struct like data and list for lists of data, which is what your data sounds like to me.
with open("config") as infile:
config = tuple(infile)
You may want to try using chained generators to create your tuple. You can use the generators to perform multiple filtering and transformation operations on your input without creating intermediate lists. All of the generator processing is delayed until iteration. In the example below the processing/iteration all happens on the last line.
Like so:
f = open('settings.cfg')
step1 = (tuple(i.strip() for i in l.split(':', 1)) for l in f if len(l) > 2 and ':' in l)
step2 = ((l[0], ',' in l[1] and 'Tag' in l[0] and l[1].split(',') or l[1]) for l in step1)
t = tuple(step2)

Categories