My question is te following:
I'm new to Python programming and I'm a little confused about the correct use of lists.
When I want for example to create a list of 10 elements I am doing something like:
list = [None for x in range(10)]
And when I have something to put on it, I do:
list[lastPosition] = data
But after some research I noticed that this use for lists is not efficient or recommended. But how other way could a list be inicialized before I have all the data? My idea is to have a list (specially something like Java's Collections) inicialized and as the data comes I fill it.
I hope my question is clear enough.
If you don't know in advance how many elements will be in the list,
then don't try to allocate 10 elements. Start with an empty list and use the append function to append to it:
lst = []
...
lst.append(value)
If for some reason you really need to initialize a list to a constant size,
and the initial elements are immutable values,
then you can do that like this:
lst = [None] * 10
If the initial elements are mutable values,
you most probably don't want to use this technique,
because all the elements will all point to the same instance.
In that case your original technique is mostly fine as it was:
lst = [SomeClass() for _ in range(10)]
Note that I renamed the variable from list to lst,
because list is a built-in class in Python,
and it's better to avoid such overlaps.
Related
Is there a more efficient, simpler way to create a tuple of lists of length 'n'?
So in Python, if I wanted to create a list of lists I could do something like:
[[] for _ in range(list_length)]
And to create a tuple of lists of a similar nature I could technically write:
tuple([[] for _ in range(list_length)])
But is this computationally inefficient, could it be written in a nicer way?
Warning: For anyone else who thought it was good idea to put mutable objects such as lists inside a tuple (immutable); it actually appears to be generally faster (computationally) to just use a list (in my case a list of lists).
Use a genex instead of a LC.
tuple([] for _ in range(list_length))
Try this:
tuple = (elements,) * list_length
This is python 3.
Lets say I have a tuple
tup = (1, 2, 3)
And this tuple is stored in a list:
a = []
a[0] = tup
I am iterating over the list a. What I need to do is modify the contents of tup. That is, I want to change the values, while keeping it in the list a.
Is this correct?
tmp = list(a[0])
tmp[0] = 0 # Now a[0] = (0, 2, 3)
Furthermore: I am aware tuples are designed to be immutable, and that a list is probably better for tup instead of a tuple. However, I am uncomfortable using append to add elements to the list: the list is storing elements of a fixed size, and a tuple is a better representative of this. I'd rather add things manually to the list like tup[0] = blah than tup.append(blah)
The answer to this is simple. You can't, and it doesn't make any sense to do so. Lists are mutable, tuples are not. If you want the elements of a to be mutable, have them as lists, eg, a = [[1,2,3],...].
If you really wanted to have them as tuples, but change them, you could do something along the lines of a[0] = (0,)+a[0][1:]. This would create a new tuple in the list, and would be less efficient than just using a list of lists.
Furthermore: I am aware tuples are designed to be immutable, and that a list is probably better for tup instead of a tuple.
It is.
However, I am uncomfortable using append to add elements to the list: the list is storing elements of a fixed size, and a tuple is a better representative of this.
I'm not sure what you mean by this. Do you mean that a is a fixed size, or elements of a are a fixed size? In either case, how does this make tuples better?
The confusion here might be that lists in Python are not lists in a computer science sense; they are actually arrays. They are O(1) for retrieval, O(1) for setting elements, and usually O(1) for appends unless they need to be resized.
I'd rather add things manually to the list like tup[0] = blah than tup.append(blah)
You can't do that with a tuple, but you can do either with a list, and they're both around O(1).
If you really want fixed-size, mutable arrays, you could look at numpy, or you could initialize python lists of set sizes.
Good morning everybody,
my simple question is the following: I have 2 lists (let's call them a and b) of length T and I want to eliminate K random elements (with the same index) from each of them.
Let's suppose for the moment K << T, in order to neglect the probability to extract the same index twice or more. Can I simply generate a list aleaindex of K random numbers and pass it to del, like
for i in range(K):
aleaindex.append(random.randint(0, T-1))
del a[aleaindex]
del b[aleaindex]
And is there some Python trick to do this more efficiently?
Thank you very much in advance!
No, there is no way to do this.
The reason for this is that del deletes a name - if there is still another name attached to the object, it will continue to exist. The object itself is untouched.
When you store objects in a list, they do not have names attached, just indices.
This means that when you have a list of objects, Python doesn't know the names that refer to those objects (if there are any), so it can't delete them. It can, at most, remove them from that particular list.
The best solution is to make a new list that doesn't contain the values you don't want. This can be achieved with a list comprehension:
new_a = [v for i, v in enumerate(a) if i not in aleaindex]
You can always assign this back to a if you need to modify the list (a[:] = ...).
Note that it would also make more sense to make aleaindex a set, as it would make this operation faster, and the order doesn't matter:
aleaindex = {random.randint(0, T-1) for _ in range(K)}
I have an unsorted list of integers in a Python list. I want to sort the elements in a subset of the full list, not the full list itself. I also want to sort the list in-place so as to not create new lists (I'm doing this very frequently). I initially tried
p[i:j].sort()
but this didn't change the contents of p presumably because a new list was formed, sorted, and then thrown away without affecting the contents of the original list. I can, of course, create my own sort function and use loops to select the appropriate elements but this doesn't feel pythonic. Is there a better way to sort sublists in place?
You can write p[i:j] = sorted(p[i:j])
This is because p[i:j] returns a new list. I can think of this immediate solution:
l = p[i:j]
l.sort()
a = 0
for x in range(i, j):
p[x] = l[a]
a += 1
"in place" doesn't mean much. You want this.
p[i:j] = list( sorted( p[i:j] ) )
I've started teaching myself Python, and as an exercise I've set myself the task of generating lookup tables I need for another project.
I need to generate a list of 256 elements in which each element is the value of math.sin(2*i*pi/256). The problem is, I don't know how to generate a list initialized to "dummy" values that I can then use a for loop to step through and assign the values of the sin function.
Using list() seems to create an "empty" list, but with no elements so I get a "list assignment index out of range" error in the loop. Is there a way to this other than explicitly creating a list declaration containing 256 elements all with "0" as a value?
Two answers have already shown you how to build your list at a single stroke, using the "list comprehension" (AKA "listcomp") construct.
To answer your specific question, though,
mylist = [None] * 256
is the simplest way to make a list with 256 items, all None, in case you want to fill it in later.
If you start with an empty list, call its .append(...) method to add each item at the end. A loop doing nothing but append on an initially-empty list is what normally gets replaced with a more concise listcomp.
Of course, for the task you actually state,
mylist = [math.sin(2 * math.pi/256)] * 256
would be by far the best approach -- no sense computing a sin 256 times when the argument's always the same (daringly assuming that what you say is what you mean;-).
my_list = [math.sin(2 * math.pi/256) for i in xrange(256)]
You can also try:
l = []
for i in range(256):
l.append(math.sin(2*math.pi/256))
This is an iterative for loop that keeps adding the same value to the end of the list 256 times
I need to generate a list of 256
elements in which each element is the
value of math.sin(2*math.pi/256)
To answer your question literally:
my_list=[math.sin(2*math.pi/256)]*256
Thanks for the help, everyone. I did make a mistake in the specification I posted for the question, in that the value of each element in the list needs to be the sin of the angle incremented by 2*pi/256 each time. The code that works for me in that case is:
li = [math.sin((2*math.pi/256)*i) for i in xrange(0,256)]