Insert on python list on a particular offset - python

I'm having a python list preinitialized like this:
eventarray=[None]*10000
Is there any other way to preinitialize this list,so that 10000 can be a variable to be changed from different functions inside,without changing the data in the list.
Note:preinitialisation is done for inserting value on a particular offset of list.

It is hard to tell exactly what you are asking, so this might not be what you want. If it is not, you should clarify your question.
To create a list of n elements where every element is None, you can do this:
myList = [None]*n
n must be in scope to do this, and future changes to n will not effect the list length.
If you want to insert a value into a list, and shift the rest of the values right, you can use list.insert(i,x):
myList = [None]*10000
myList.insert(5,0)
This will insert a 0 at index 5, and will shift the remaining values (indices 5 and higher) to the right one. This results in a list who's length is one more than before the insert. If you just want to set a value in your list:
myList = [None]*10000
myList[5] = 0
This will result in a list of 10,000 elements with the 6th element (index of 5) being 0. The length of the initial and final lists will be the same.

From what I can infer from your question, you want to create a list with global scope, with its length determined at runtime.
Edit: The following code now extends the list as necessary each time my_list_creator is accessed:
foo = []
def my_list_creator(n):
'''Makes the nth value in a list n. If the list is not
long enough, it extends it, initialised with None.
'''
global foo
if len(foo) < n:
foo.extend([None] * (n - len(foo)))
foo[n-1] = n
def access_a_global():
print foo
def another_func():
my_list_creator(10)
access_a_global()
my_list_creator(20)
access_a_global()
another_func()
foo is global in scope, but is initialised as necessary.

Related

first list gets auto updated aftter appending another second list to it and then changing the second list in Python

please take a look at this code
a = [int(x) for x in bin(2)[2:]]
coordinates = []
sum = [1,3]
for x in a:
if x == 1:
coordinates.append(sum)
m = ((3*(sum[0]**2)+A) * libnum.invmod(2*sum[1],p)) % p
x3 = (m**2 - 2*sum[0]) % p
sum[1] = ((m*(sum[0]-x3) - sum[1]) + p) % p
sum[0] = x3
my sum list gets updated in the loop and the new values should be added to the coordinates list if they match the conditions. the problem is that after appending the sum list to the coordinates list whenever the values change in sum they also change in coordinates. there is some kind of link between them. Can you please help me with this problem? How can I unlink them so that just the values are appended and stay fixed.
This is because when you assign a list value to a new variable, it only stores the reference number, when you append this variable to a new list, the same reference number is being used. So when you later change the value, it changes the values of the list defined by that reference number, hence changing what that variable stores wherever it was used.
e.g
coordinates = []
some = [1,3] # avoid using 'sum' as variable name as it is a built in function
coordinates.append(some)
print("coordinates initially:", coordinates)
some.append("interesting")
print("coordinates after chaning 'some':", coordinates)
Output:
coordinates initially: [[1, 3]]
coordinates after chaning 'some': [[1, 3, 'interesting']]
This doenst make sense for small lists but when you consider that lists can hold huge amounts of values, it makes it much faster to use reference numbers
Thus, the solution is that we need to infact append a copy of the some list and not just the reference number.
For this, we can do the following:
import copy
# We can use the copy.deepcopy() function and pass it the list we need copied
coordinates.append(copy.deepcopy(some))

loop with strange return function?

I have a question about the below code, particularly the 6th line; is it right to say that it is returning the index of target-nums[I]? If so, why is there another I after it?
Also, what is comp[nums[I]] = I doing? Is it assigning values of nums into comp if it is not in comp already?
Finally, what is the final return [ ] doing in the last line of code?
def TwoSum(nums, target):
comp = {}
for i in range(len(nums)):
if (target - nums[i]) in comp:
return [comp[target - nums[i]],i]
comp[nums[i]] = i
return []
print(TwoSum(nums,target))
is it right to say that it is returning the index of target-nums[I]?
If so, why is there another 'I' after it?
It is returning a list of two items, the first item being comp[target - nums[i]], and the second item being i. It's the same idea as:
def addAndSubtract(x, y):
return [x+y, x-y]
Above, we return a list, the first item in the list is the value of evaluating x+y and the second value is the result of evaluating x-y.
Also, what is comp[nums[I]] = I doing? Is it assigning values of nums into comp > if it is not in comp already?
This will assign the value of nums[i] as a key in your comp dictionary and assign it the value of i. It essentially stores the current value in nums and along with its index. This does two things:
Allows you to easily and quickly check if you have seen a given number yet by checking if it is a key in your comp dictionary
Allows you to check where that number was last seen in your list.
The comp[nums[i]] = i occurs each time your for loop runs, so it will do it for all numbers, in your list, unless it returns in your if-statement. If you happen to encounter the same number again (which is already in your list), then this assignment will simply overwrite the value with the current index of the current number (ie: i).
Finally, what is the final return [ ] doing in the last line of code?
The purpose of this is to return an empty list. It is just a way to signify that no result was found. You will only reach that return when you have iterated through all the numbers in your list and not returned from within your for loop, thus indicating no sum can be made to reach the target.
I explain how this algorithm works in detail here, so you might want to check that out if you need more of an explanation. Although the question is a JavaScript question, the logic explained is the exact same as this.

Why am I getting an infinite for loop?

For this python problem I am taking in one argument an int, this is the max length of a list I am going to be appending to. Starting with an int value of 1, I want to iterate through the list appending two more linear values until the max length is reached.
I am getting an infinite loop or something similar; I am not receiving any values but python is still processing.
This is the code where the infinite loop is occurring, wondering why?
Code:
def dbl_linear(n):
lst_u =[1]
while len(lst_u)<=n:
for i in lst_u:
lst_u.append(2*i+1)
lst_u.append(3*i+1)
return sorted(lst_u)
dbl_linear(10)
I looked up this example user had set a variable to another variable that contained a list before the for loop and then changed it back after the loop. Wondering why this is done and why it is useful?
other code:
d
ef dbl_linear(n):
lst_u =[1]
while len(lst_u)<=n:
new_u = lst_u
for i in lst_u:
new_u.append(2*i+1)
new_u.append(3*i+1)
new_u=lst_u
return sorted(lst_u)
dbl_linear(10)
You are adding to the list as you loop over it. A list iterator simply increments a position counter and returns the value at that index until the index doesn't exist. It doesn't keep track of the length of the list up-front. In your case, by adding more elements to the end, the iterator never reaches an index that doesn't exist.
You have several options:
Create a copy of the list first to iterate over; that copy won't grow:
def dbl_linear(n):
lst_u = [1]
while len(lst_u)<=n:
for i in lst_u[:]: # [:] returns a shallow copy
lst_u.append(2*i+1)
lst_u.append(3*i+1)
return sorted(lst_u)
Append to a separate, new list and extend the original after the loop:
def dbl_linear(n):
lst_u = [1]
while len(lst_u)<=n:
new_values = []
for i in lst_u:
new_values.append(2*i+1)
new_values.append(3*i+1)
lst_u.extend(new_values)
return sorted(lst_u)
Use a range() to produce indices; this is based on taking the length once:
def dbl_linear(n):
lst_u = [1]
while len(lst_u)<=n:
for idx in range(len(lst_u)):
i = lst_u[idx]
lst_u.append(2*i+1)
lst_u.append(3*i+1)
return sorted(lst_u)

Dynamic substrings on List. 10 elements before variable

I have problem with dynamic substrings. I have list which can have 1000 elements, 100 elements or even 20. I want to make copy of that list, which will have elements from -10 to variable.
For example(pseudo-code):
L = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
variable = 12
print L[substring:variable]
>>> L = [2,3,4,5,6,7,8,9,10,12]
I can't figure out how make it correct. The point is that variable is always changing by one.
Here is my piece of code:
def Existing(self, Pages):
if(self.iter <= 10):
list = self.other_list[:self.iter]
else:
list = self.other_list[self.iter-10:self.iter]
result = 0
page = Pages[0]
list.reverse()
for blocks in Pages:
if(list.index(blocks) > result):
result = list.index(blocks)
page = blocks
return page
That method is looking for the element which has the farest index.
This part can be unclear. So assume that we have
list = [1,2,3,4,1,5,2,1,2,3,4]
Method should return 5, because it is the farest element. List has duplicates and .index() is returning index of the first element so i reverse list. With that code sometimes program returns that some element do not exist in List. The problem (after deep review with debbuger) is with substrings in self.other_list.
Could you help me with that problem? How to make it correct? Thanks for any advice.
EDIT: Because my problem is not clear enough (I was sure that it can be), so here are more examples.
Okay, so list Pages are list which cointains currently pages which are used. Second list "list" are list of all pages which HAS BEEN used. Method is looking for pages which are already used and choose that one which has been not used for the longest time. With word "use" I mean the index of element. What means the farest element? That one which the smallest index (remember about duplicates, the last duplicates means the real index).
So we have:
Pages = [1,3,5,9]
and
list = [1,2,5,3,6,3,5,1,2,9,3,2]
Method should return 5.
To sum up:
I'm looking for substring which give result:
With list =[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
For variable 12: [2,3,4,5,6,7,8,9,10,12]
for 13: [3,4,5,6,7,8,9,10,11,13]
ect :-)
I know that problem can be complicated. So i would aks you to focus only about substrings. :-) Thanks you very much!
If I understood your problem correctly you want to find the index of items from pages that is at minimum position in lst(taking duplicates in consideration).
So, for this you need to first reverse the list and then first the index of each item in pages in lst, if item is not found then return negative Infinity. Out of those indices you can find the max item and you'll get your answer.
from functools import partial
pages = [1,3,5,9]
lst = [1,2,5,3,6,3,5,1,2,9,3,2]
def get_index(seq, i):
try:
return seq.index(i)
except ValueError:
return float('-inf')
lst.reverse()
print max(pages, key=partial(get_index, lst))
#5
Note that the above method will take quadratic time, so it won't perform well for huge lists. If you're not concerned with some additional memory but linear time then you can use set and dict for this:
pages_set = set(pages)
d = {}
for i, k in enumerate(reversed(lst), 1):
if k not in d and k in pages_set:
d[k] = len(lst) - i
print min(d, key=d.get)
#5

How do I handle the following situation in Python?

I want to say
a[current] = value
rather than saying
a.append(value)
because I want to show that the current value is value. The former listing shows this better. I come from C, so I am a bit confused with python lists. In C I preallocate space, so a[current] would exist and contain junk before I assign it value. Can I do something similar in Python?
You can do something like
[0] * 10
which will result in
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
But your approach will probably not be very "pythonic". If switching to Python, you should also think about thinking in python. ;-)
When I first started using Python I ran into this problem all the time. You can do things like '[0]*10', but is inelegant, and will cause you problems if you try to do the same thing for lists of lists.
I finally solved the problem by realizing most of the time I just needed to reformulate the problem into something more pythonic. List comprehensions (as noted above) will almost always be the correct answer. If you are preallocating space, that means you are probably going to iterate over some other list, do some operation, then set an element in the new list to that value:
newList = [op(e) for e in oldList]
You can get fancier. If for example, you don't want all the elements, you can set up a filter:
newList = [op(e) for e in oldList if e < 5]
which will only put items that are less than 5 into the newList.
However, sometimes list comprehension isn't want you want. For example, if you're doing math-oriented coding, then numpy can come to the rescue:
myVector = numpy.zeros(10)
will create an array with 10 elements.
You can allocate a list of length n by using
my_list = [None] * n
Obviously, the list will be initialised rather than containing junk.
That said, note that often a list comprehension is a good replacement for a loop containing calls to list.append().
If you want to create a list with n elements initialized to zero (read "preallocate") in Python, use this:
somelist = [0] * n
Is this what you want?
If you don't like append, you can do things like
a = [None]*10
for i in range(10):
a[i] = something()
you might be interested also in python arrays.
I think that the most approximate syntax would be:
a.insert(current, value)
but if current isn't the last position in the array, insert will allocate some extra space and shift everything after current in one position. Don't know if this is the desired behavior. The following code is just like an append:
a.insert(len(a), value)
If you want to show that the current value is 'value', why don't you just use a variable for it?
a.append(value)
current_value = value
If you are maintaining a separate current variable to indicate where the next item will be inserted (that is, your line a[current] = value is followed immediately by current += 1 and you wish you could just write a[current++] = value), then you're writing C in Python and should probably stop. :-)
Otherwise you probably want to preallocate the list with the number of items you want it to contain, as others have shown. If you want a list that will automatically extend to fill in missing values, such that a[100] = value will work even if the list only has 50 items, this can be done with a custom __setitem__() method on a list subclass:
class expandinglist(list):
def __setitem__(self, index, value):
length = len(self)
if index < length:
list.__setitem__(self, index, value)
elif index = length: # you don't actually need this case, it's just a bit
self.append(value) # faster than the below for adding a single item
else:
self.extend(([0] * (index - length)) + [value])
lyst = expandinglist()
lyst[5] = 5
print lyst
>> [0, 0, 0, 0, 0, 5]

Categories

Resources