Adding a list to itself after addition to each value - python

I have a list of integers that follows a particular pattern, it's complex but for example say:
x = [0,2,4,6,8]
I'd like to extend the list with 9 more copies of itself, but add a constant value that linearly scales each time. E.g. if
constant = 10
loop = 9
Then the 2nd extension would result in:
x_new = [0,2,4,6,8,10,12,14,16,18]
So I think I want a loop that iterates through x and extends the array by x[i]+constant, loop number of times?
for i in range(loop):
for j in range(len(x)):
x_new = x.extend((x[j]+constant)*i)
Or perhaps this can be easily done through list comprehension? My actual list is ~3000 long and I'll be doing it a few times with different values of loop and constant.

Yes, list comprehension should work:
x_new = [ e + constant * i for i in range(loop+1) for e in x ]

I just did some work on above question, this code can be useful for above question.
x=[0,2,4,6,8]
y=x[4]
i=0
j=0
while(i<9):
z=range(y+2,y+12,2)
x.extend(z)
print x
y=y+10
i=i+1

Related

Creating data in loop subject to moving condition

I am trying to create a list of data in a for loop then store this list in a list if it satisfies some condition. My code is
R = 10
lam = 1
proc_length = 100
L = 1
#Empty list to store lists
exponential_procs_lists = []
for procs in range(0,R):
#Draw exponential random variables
z_exponential = np.random.exponential(lam,proc_length)
#Sort values to increase
z_exponential.sort()
#Insert 0 at start of list
z_dat_r = np.insert(z_exponential,0,0)
sum = np.sum(np.diff(z_dat_r))
if sum < 5*L:
exponential_procs_lists.append(z_dat_r)
which will store some of the R lists that satisfies the sum < 5L condition. My question is, what is the best way to store R lists where the sum of each list is less than 5L? The lists can be different length but they must satisfy the condition that the sum of the increments is less than 5*L. Any help much appreciated.
Okay so based on your comment, I take that you want to generate an exponential_procs_list, inside which every sublist has a sum < 5*L.
Well, I modified your code to chop the sublists as soon as the sum exceeds 5*L.
Edit : See answer history to see my last answer for the approach above.
Well looking closer, notice you don't actually need the discrete difference array. You're finding the difference array, summing it up and checking whether the sum's < 5L and if it is, you append the original array.
But notice this:
if your array is like so: [0, 0.00760541, 0.22281415, 0.60476231], it's difference array would be [0.00760541 0.21520874 0.38194816].
If you add the first x terms of the difference array, you get the x+1th element of the original array. So you really just need to keep elements which are lesser than 5L:
import numpy as np
R = 10
lam = 1
proc_length = 5
L = 1
exponential_procs_lists = []
def chop(nums, target):
good_list = []
for num in nums:
if num >= target:
break
good_list.append(num)
return good_list
for procs in range(0,R):
z_exponential = np.random.exponential(lam,proc_length)
z_exponential.sort()
z_dat_r = np.insert(z_exponential,0,0)
good_list = chop(z_dat_r, 5*L)
exponential_procs_lists.append(good_list)
You could probably also just do a binary search(for better time complexity) or use a filter lambda, that's up to you.

problem with nested while loops in Python

I have 2 lists of names, names_1 and names_2, they are both of the same length (1000), no list has duplicate names, each list contains 1000 unique names, but some names appear in both lists, I want to isolate the names that appear in both lists in a third list dup_names and remove them from the original lists, I tried the following code but it didn't work:
dup_names=[]
m=len(names_1)
i=0
k=0
COMPARED=[]
while i<m:
while k<m:
COMPARED.append((i,k))
if names_1[i]==names_2[k]:
dup_names.append(names_1[i])
names_1[i:i+1]=[]
names_2[k:k+1]=[]
m=m-1
k=0
else:
k=k+1
i=i+1
for i_k_pair in COMPARED:
print(i_k_pair)
print('len(COMPARED) =',len(COMPARED))
print('len(dup_names) =',len(dup_names))
print('len(names_1) =',len(names_1))
print('len(names_1) =',len(names_2))
I created the "COMPARED" list to check what (i,k) values got compared to each other, the output was:
(0,0)
(0,1)
.
.
.
(0,999)
len(COMPARED) = 1000
len(dup_names) = 0
len(names_1) = 1000
len(names_2) = 1000
from the i_k_pairs that got printed, I see that it only compaired the 1st name in names_1 (i=0) to all names in names_2, since len(dup_names) = 0, len(names_1) = 1000 and len(names_2) = 1000, I expext that len(COMPARED) = 1000000 but it looks like the is a problem with the outed loop, can anyone please explain what's wrong to me?!?!
I know that I can do the job with the following code:
dup_names=[]
for i in range(len(names_1)):
for k in range(len(names_2)):
if names_1[i]==names_2[k]:
dup_names.append(names_1[i])
new_names_1=[]
new_names_2=[]
for n in range(len(names_1)):
s1=0
s2=0
for m in range(len(dup_names)):
if names_1[n]==dup_names[m]:
s1=1
if names_2[n]==dup_names[m]:
s2=1
if s1==0:
new_names_1.append(names_1[n])
if s2==0:
new_names_2.append(names_2[n])
names_1=new_names_1
names_2=new_names_2
del new_names_1,new_names_2
I tried this code and it worked just fine, but what's really puzzling me is:
what's wrong with the first code???
why the outer while loop didn't work?!
is there a problem with nested while loops in Python?
This is comparing the two lists for duplicates and never compares anything already compared in names_1. I think there might be a well optimized one for this. If you wanna compare the two lists len(names_1) times len(names_2) better avoid removing elements from names_1 and names_2. The reason your code didn't work is, your code was not resetting i=0 to start the names_1 from the beginning after the second while loop.
dup_names=[]
names_1=["a","b","c","d","e"]
names_2=["f","g","h","a","d"]
m=len(names_1)
n=len(names_2)
i=0
k=0
COMPARED=[]
while i<m:
matched_any = False
while k<n:
COMPARED.append((i,k))
if names_1[i]==names_2[k]:
dup_names.append(names_1[i])
names_1[i:i+1]=[]
names_2[k:k+1]=[]
matched_any = True
break
else:
k=k+1
i=0
k=0
if not matched_any:
names_1[i:i+1]=[]
m=len(names_1)
n=len(names_2)
for i_k_pair in COMPARED:
print(i_k_pair)
print('len(COMPARED) =',len(COMPARED))
print('len(dup_names) =',len(dup_names))
print('len(names_1) =',len(names_1))
print('len(names_1) =',len(names_2))
Use Pythonic approach and set for solving your problem.
x = ["C++", "C", "Python"]
y = ["Java", "C"]
z = set(x).intersection(set(y))
x = [elt for elt in x if elt not in z]
y = [elt for elt in y if elt not in z]

Python - Splitting lists of integers during iteration

I have an array of data where I'm taking a slice through a 3D array of floats and appending the numbers of the elements that satisfy a set of upper and lower bounds (also floats).
The first part of my code contains a nested for loop in the style of the following:
x_lst = []
for i in range(len(x1)):
for x in range(len(floatarray[0,:,0])):
if x1[i] <= floatarray[0,x,0] <= x2[i]:
x_lst.append(x)
#issues after this point
The inner loop compares the data in the array (floatarray[0,x,0]) with the boundaries x1 and x2, returning a list of integers, whilst the outer loop iterates through the values of the boundaries.
The issue I have is that the output (x_lst) is a single list, whereas I've been trying to produce a list of lists, with each sublist corresponding to the iterable i.
e.g.
#Desired output
x_lst = [[5,6,7,13,14],[21,22,23,36,37],[44,45,...
#Actual output
x_lst = [5,6,7,13,14,21,22,23,36,37,44,45,...
I feel like there's a very simple way of doing this, but I've not been able come up with anything that works (such as trying to use x_lst.split() after the append).
Also, any feedback on the question would be great as I'm still fairly new to SO.
It seems the following should work: why not create an intermediate sublist for each i, and add appropriate values to the sublist, then finally add the sublist to the main list?
x_lst = []
for i in range(len(x1)):
inner_list = [] # The sublist to be appended.
for x in range(len(floatarray[0,:,0])):
if x1[i] <= floatarray[0,x,0] <= x2[i]:
inner_list.append(x) # Add the numbers to the sublist.
# Issues after this point...
x_lst.append(inner_list) # Add the sublist to the main list.
Everything appears to be correct in the code except that you append into a 1-d array. For solving your problem you can simply change your code so that a temporary array named temp will append data in inner loop which would then be appended to your outer array x_lst as shown below:
x_lst = []
for i in range(len(x1))
temp=[]
for x in range(len(floatarray[0,:,0])):
if x1[i] <= floatarray[0,x,0] <= x2[i]:
temp.append(x)
x_lst.append(temp);
Okay, so Sam's answer is correct insofar as appending the values through the iteration, but trying it out with my code produced lists of lists of len(i) where each sublist contained all values of x that satisfied all elements of x1 and x2, instead of each list containing values specific to the [i]th element of x1 and x2, thus all the sublists were identical.
I got around this by replacing the inner for loop with a list comprehension, as follows, that gave the right result (in the desired form x_lst = [[5,6,7,13,14],[21,22,23,36,37],[44,45,...):
x_lst = []
for i in range(len(x1)):
y = [x for x in range(len(floatarray[0,:,0])) if x1[i] <= floatarray[0,x,0] <= x2[i]]
x_lst.append(y)

Difference In List - Python - Syntax Explanation [duplicate]

This question already has answers here:
Explanation of how nested list comprehension works?
(11 answers)
Closed 6 years ago.
Can someone please explain the meaning the syntax behind the following line of code:
temp3 = [x for x in temp1 if x not in s]
I understand it's for finding the differences between 2 lists, but what does the 'x' represent here? Each individual element in the list that is being compared? I understand that temp1 and s are lists. Also, does x for x have to have the same variable or could it be x for y?
[x for x in temp1 if x not in s]
It may help to re-order it slightly, so you can read the whole thing left to right. Let's move the first x to the end.
[for x in temp1 if x not in s yield x]
I've added a fake yield keyword so it reads naturally as English. If we then add some colons it becomes even clearer.
[for x in temp1: if x not in s: yield x]
Really, this is the order that things get evaluated in. The x variable comes from the for loop, that's why you can refer to it in the if and yield clauses. But the way list comprehensions are written is to put the value being yielding at the front. So you end up using a variable name that's not yet defined.
In fact, this final rewrite is exactly how you'd write an explicit generator function.
def func(temp1, s):
for x in temp1:
if x not in s:
yield x
If you call func(temp1, s) you get a generator equivalent to the list. You could turn it into that list with list(func(temp1, s)).
It iterates through each element in temp1 and checks to see if it is not in s before including it in temp3.
It is a shorter and more pythonic way of writing
temp3 = []
for item in temp1:
if item not in s:
temp3.append(item)
Where temp1 and s are the two lists you are comparing.
As for your second question, x for y will work, but probably not in the way you intend to, and certainly not in a very useful way. It will assign each item in temp1 to the variable name y, and then search for x in the scope outside of the list comprehension. Assuming x is defined previously (otherwise you will get NameError or something similar), the condition if x not in s will evaluate to the same thing for every item in temp1, which is why it’s not terribly useful. And if that condition is true, your resulting temp3 will be populated with xs; the y values are unused.
Do not take this as saying that using different variables in a list comprehension is never useful. In fact list comprehensions like [a if condition(x) else b for x in original_sequence] are often very useful. A list comprehension like [a for x in original_sequence if condition(x)] can also be useful for constructing a list containing exactly as many instances of a as the number of items in original_sequence that satisfy condition().
Try yourself:
arr = [1,2,3]
[x+5 for x in arr]
This should give you [6, 7, 8] that are the values on the [1,2,3] list plus 5. This syntax is know as list comprehension (or mapping). It applies the same instructions to all elements on a list. Would be the same as doing this:
for x in arr:
arr += 5
X is same variable and it is not y. It works same as below code
newList = []
for x in temp1:
if x not in s:
newList.append(x)
So x for x, here first is x which is inside append in code and x after for is same as for x in temp1.

How is this 2D array being sized by FOR loops?

Question background:
This is the first piece of Python code I've looked at and as such I'm assuming that my thread title is correct in explaining what this code is actually trying to achieve i.e setting a 2D array.
The code:
The code I'm looking at sets the size of a 2D array based on two for loops:
n = len(sentences)
values = [[0 for x in xrange(n)] for x in xrange(n)]
for i in range(0, n):
for j in range(0, n):
values[i][j] = self.sentences_intersection(sentences[i], sentences[j])
I could understand it if each side of the array was set with using the length property of the sentences variable, unless this is in effect what xrange is doing by using the loop size based on the length?
Any helping with explaing how the array is being set would be great.
This code is actually a bit redundant.
Firstly you need to realize that values is not an array, it is a list. A list is a dynamically sized one-dimensional structure.
The second line of the code uses a nested list comprehension to create one list of size n, each element of which is itself a list consisting of n zeros.
The second loop goes through this list of lists, and sets each element according to whatever sentences_intersection does.
The reason this is redundant is because lists don't need to be pre-allocated. Rather than doing two separate iterations, really the author should just be building up the lists with the correct values, then appending them.
This would be better:
n = len(sentences)
values = []
for i in range(0, n):
inner = []
for j in range(0, n):
inner.append(self.sentences_intersection(sentences[i], sentences[j]))
values.append(inner)
but you could actually do the whole thing in the list comprehension if you wanted:
values = [[self.sentences_intersection(sentences[i], sentences[j]) for i in xrange(n)] for j in xrange(n)]

Categories