How to keep specific element indexs in an array - python

Suppose I have two arrays:
a = [1, 4, 9, 16, 25, 36, 49, 64, 81]
b = [2,5,7]
And I want to keep the elements indexed in a that are listed in b so the 2nd, 5th and 7th index of a:
a_new = [4, 25, 49]
I will then plot b against a_new / perform analysis on it.
For my application, a is a long series of simulated data, and b is a time series of when I want to sample from this data.
Thanks

First remember that the first element of an array (or in this case a list) is number 0 and not number 1:
a = [1, 4, 9, 16, 25, 36, 49, 64, 81]
a[0] = 1 # How to adress the first element
a[1] = 4 # How to adress the second element
a[2] = 9 # ...
So the elements you want (as specified in the array b) are:
a[1] = 4 # a[1] is the same as a[2 - 1] (note that b[0] = 2)
a[4] = 25 # a[4] is the same as a[5 - 1] (note that b[1] = 5)
a[6] = 49 # a[6] is the same as a[7 - 1] (note that b[2] = 7)
So you can also access the elements this way:
a[ b[0] - 1 ] = 4 # Same as a[1] which is the second element
a[ b[1] - 1 ] = 25 # Same as a[4] which is the fifth element
a[ b[2] - 1 ] = 49 # Same as a[6] which is the seventh element
This can be wrapped up in a for-loop:
a_new = [] # Start with an empty list
for index in b: # index in b are all elements in b, thus: b[0] = 2, b[1] = 5 and b[2] = 7
a_new.append(a[ index - 1])
This loop will put the elements a[2 - 1] (4), a[5 - 1] (25) and a[7 - 1] (49) into the lista_new.
But there is a shorter way to write that loop:
a_new = [ a[ index - 1] for index in b ]
Basically, you say a_new = [ ... ], so a_new is a list, and the ... inside will specify, what the list will be filled with. In this case, it will be the elements that the for-loop produces, note that a[ index - 1] for index in b is the same for-loop as in the first example, written in a compact way.
What if you get an list index out of range error?
Your lista contains 9 elements, so the first element is a[0] and the last is a[8]. If you try to access any other element in a list, for example a[12], you will get a "list index out of range" error.
That means: the list b should only contain numbers between 1 and 9 (the length of the list, which you can find out this way len[a] = 9).
I would recommend, that you change your list b to b = [1, 4, 6], since the fifth element of an array is actually adressed like a[4] and not a[5].
The code will be a bit easier:
a_new = [ a[index] for index in b ]
If you don't want errors to happen, the values in b should then be between 0 and 8 (which is len(a) - 1), since a[0] is the first and a[8] is the last element, and only elements between that exist!

There are two possible problems that you may be encountering, both of which have been somewhat mentioned in the comments. From what I see, you either have a problem reading the or you have an invalid index in b.
For the former, you may actually want
a = [1, 4, 9, 16, 25, 36, 49, 64, 81]
b = [2,5,7]
To produce:
a_new = [9, 36, 64]
Since you always count starting from zero:
[1, 4, 9, 16, 25, 36, 49, 64, 81]
0 1 2 3 4 5 6 7 8
Hence, leading to an XY problem, where you try to solve a problem your way which is the wrong way. Therefore, it wastes our time to try to fix a problem that doesn't work since it is actually something else.
However, for the latter, you may have an anomaly in your b list. The way to index the list (given in the comments) as you wanted is using list comprehension:
a_new = [a[i-1] for i in b]
What this does is:
a_new = []
for i in b:
a_new.append(a[i-1])
Hence, when i is larger than or equal to len(a), it evaluates to an invalid index:
>>> a = [1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> len(a)
9
>>> a[9]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range

Related

How do I convert a list into an array?

I have a list and a (2 by 2) array.
I want to multiply the first two values of the list with this array 'k' shown below,
(of course by converting these two values into a (2 by 1) array).
Then I want to do the same procedure with the next two values( i.e 2nd and 3rd values).
its like [1,2] , then [2,3] ...[3,4] [4,5] ...( these each couple of lists must be in 2 by 1 array so that I can further multiply it with k (2 by 2 array) mentioned below )
The array 'k' in all the cases is the same.
How do I make this loop?
my_List = [1, 2, 3, 4, 5, 6, 7, 8,9, 10, 11, 12, 13,14, 15, 16, 17 ,18 ,19, 20, 21, 22, 23, 24, 25, 26,27 ,28 ,29, 30, 31 ,32, 33, 34,35 ,36, 37, 38, 39]
E = 1
I = 1
l = 1
k = np.array( [ [4*E*I/ l, 2*E*I/ l ],
[2*E*I/ l, 4*E*I/ l ] ] )
Is this the solution you are looking for? If not add some expected output so that this can be edited accordingly.
import numpy as np
# Turn my_List into list of (2 by 1) arrays
twosArray = [np.array([my_List[i], my_List[i+1]]) for i in range(0, len(my_List)-1, 2]
# Multiply all (2 by 1) arrays by k
for array in twosArray:
prod = k.dot(array) # you can collect prod into a list if you want to use it later
print(prod)
Test:
# I'm using simpler values for my_List. You can test with your own values
my_List = [2,2,-1,-1]
# k is the same as the one in your problem
Outputs of print:
[12. 12.]
[-6. -6.]

Take the mean values of a number of integers in one list, based on the integers in another list

I have one list containing a large number of integers, and then another list also containing integers that (if added together) sums up to the total amount of integers in the first list. I wish to create a function which iterates over the second list, and for each number in the second list, takes the mean of the values in the first list and repeats for all integers in the second list...making one final third list containing the desired mean-values.
For example: A small portion of my two lists look like this: [20, 15, 20, 30, 40, 20, 10, 8], [2, 3, 1, 2]
So since 2 is the first number in my second list, I want to take the mean of the first two integers in my first list, and then the 3 next, and so on, and add these into a third list.
Here is a brief idea of what I am thinking, but its obviously not complete.
def mean_values(list_of_numbers, numbers_for_meanvalue):
list_of_means = []
for i in numbers_for_meanvalue:
mean = sum(list_of_numbers[0]+...+list_of_numbers[i])/numbers_for_meanvalue[i]
list_of_means.append[mean]
return list_of_means
you can take a slice of a list: list[start : end].
def mean_values(list_of_numbers, numbers_for_meanvalue):
list_of_means = []
last_start = 0
for num in numbers_for_meanvalue:
mean = sum(list_of_numbers[last_start:last_start + num]) / len(list_of_numbers[last_start:last_start + num])
last_start += num
list_of_means.append[mean]
return list_of_means
I don't if I understand you correctly, but:
>>> a = [20, 15, 20, 30, 40, 20, 10, 8]
>>> b = [2, 3, 1, 2]
>>> n = 0
>>> for e in b:
... sl = a[n:n+e]
... print(sl,(sum(sl) / e))
... n += e
...
[20, 15] 17.5
[20, 30, 40] 30.0
[20] 20.0
[10, 8] 9.0

Swapping opposite elements of a List of Integers if either is Odd

Write a program with the definition of a function named Array_Swap() that will accept an integer list & its size as arguments and the function will swap elements in such a way that the first element is swapped with the last element, the second element is swapped with the second last element and so on, only if anyone or both the elements are odd and display the result.
If initially, a list of seven elements is: [5, 16, 4, 7, 19, 8, 2], the contents of the list after the execution should be:
[2, 16, 19, 7, 4, 8, 5].
def Array_Swap(List,Size):
for i in range (Size//2):
List[i]=List[Size//2-i]
print(List)
L=[]
n=int(input("Enter number of elements"))
for i in range(n):
x=int(input("Enter element"))
L.append(x)
Array_Swap(L,len(L))
The size/length of the list is not relevant because it can be obtained by len(list). And even then it's not required to conditionally swap items in the list. I suggest that the Size parameter be removed, but considering it's an assignment, it can be given a default of None so that it can be ignored by the caller if desired.
The following algorithm zips the input list with its reverse to form pairs relative to their index from the front and end of the list respectively, i.e. the first and last items are paired, the second and second last are paired, etc. Once the items are paired it is simply a matter of iterating over the list and emitting the second number of the pair if either number is odd, or the first number if neither is odd - effectively swapping the pairs as required.
This is done in-place (that's what the List[:] does) with a list comprehension.
def ArraySwap(List, Size=None):
List[:] = [b if (a % 2 or b % 2) else a
for a, b in zip(List, reversed(List))]
print(List)
>>> l = [5, 16, 4, 7, 19, 8, 2]
>>> ArraySwap(l)
[2, 16, 19, 7, 4, 8, 5]
>>> l
[2, 16, 19, 7, 4, 8, 5]
>>> l = list(range(1,30))
>>> ArraySwap(l)
[29, 2, 27, 4, 25, 6, 23, 8, 21, 10, 19, 12, 17, 14, 15, 16, 13, 18, 11, 20, 9, 22, 7, 24, 5, 26, 3, 28, 1]
>>> ArraySwap([1])
[1]
>>> ArraySwap([])
[]
To swap two elements in the list, use the pattern a, b = b, a.
If i is the index of a list item, it's opposite/mirror element is -(i+1), or - i - 1.
so for the 0th element (first one), the mirror is -(0+1), = -1
using that as the indexer for the element, swap the two list elements IF
check that at least one of them is odd before swapping:
def Array_Swap(List,Size):
for i in range (Size // 2):
if List[i] % 2 == 1 or List[-(i+1)] % 2 == 1:
List[i], List[-(i+1)] = List[-(i+1)], List[i]
print(List)
L = [5, 16, 4, 7, 19, 8, 2] # use your input blocks as before, this is an example
Array_Swap(L,len(L))
Output: [2, 16, 19, 7, 4, 8, 5]
(And if L = [5, 16, 4, 7, 19, 8, 1, 2], output is [2, 1, 4, 19, 7, 8, 16, 5].)
Btw, you don't need to pass in the size of the list as a parameter.
You could do just: for i in range(len(List) // 2)
Another solution:
def Array_Swap(List, Size=None):
if Size is None:
Size = len(List)
for (i, j) in zip(range(Size // 2), range(Size - 1, Size // 2, -1)):
if List[i] % 2 or List[j] % 2:
List[i], List[j] = List[j], List[i]
print(List)
Alternatively:
Size parameter is redundant since python's list instance knows its own size
Use bitwise operatos & | >>... possibly cheaper than modulus % and divide / operations.
def Array_Swap(List):
for i in range(len(List) >> 1):
if (List[i] | List[-i-1]) & 1:
List[i], List[-i-1] = List[-i-1], List[i]
print(List)
The standard way to swap two variables in Python is:
a, b = b, a
In this case, you would do:
lst[i], lst[size - i - 1] = lst[size - i - 1], lst[i]
which swaps the ith element with the element that is at index size - i - 1 (i.e. the ith index from the end).
The other issue with your code is that it doesn't check whether either of the elements being swapped are odd, which you can resolve by adding the condition:
if lst[i] % 2 or lst[size - i - 1] % 2:
before doing the swap. This uses the modulo operator (%) to check the parity of the elements. Taking a number modulo 2 will return 1 if the number is odd. If either are odd (1 has a truth value of True), the condition would succeed and the swap will be performed.
Finally, your function was printing the list, rather than returning it. Its usually best to return a result and print the returned result.
The full working version, with the above three changes is as follows:
def list_swap(lst, size):
for i in range(size // 2):
if lst[i] % 2 or lst[size - i - 1] % 2:
lst[i], lst[size - i - 1] = lst[size - i - 1], lst[i]
return lst
l = []
n = int(input("Enter number of elements: "))
for _ in range(n):
x = int(input("Enter element: "))
l.append(x)
result = list_swap(l, len(l))
print(result)
Also note, I've changed all the variables to be lowercase, which is standard in Python.
With your shown example:
Enter number of elements: 7
Enter element: 5
Enter element: 16
Enter element: 4
Enter element: 7
Enter element: 19
Enter element: 8
Enter element: 2
[2, 16, 19, 7, 4, 8, 5]

Replace numbers in array for specific places only

There are 32 numbers in array c and all the number are 21. I want to replace the numbers in position 0,5,10,18,21,24,28 with 63. How can I do that?
a =32
b = [0,5,10,18,21,24,28]
c = []
for i in range(a):
c.append(21)
Setup:
More efficient creation of c, per Barmar
a = 32
b = [0, 5, 10, 18, 21, 24, 28]
c = [21] * a
Replace values at given indices:
list[index] allows for retrieval or assignment of a value to a specific index location in a list
for x in b:
c[x] = 63
Resources:
Python Lists

how to identify duplicate integers within a list, than minus each integer following the duplicate by one?

I am trying to solve an issue that I am currently running into. I want to have to have a list that is made up of only random integers. Then if i find a duplicate integer within this list i want to minus the rest of the list by one, after the second time the duplicate number appeared. Furthermore if a second pair of duplicate numbers are encountered, it should then minus the rest of the list by two, than if a third by three and etc.
But it should not affect the same duplicate number or any other duplicated number (that differs from the first) that is in the sequence.
For example
mylist = [0 1 2 3 4 5 6 2 8 5 10 11 12 1 14 15 16 17]
I want the end result to look like;
mylist = [0 1 2 3 4 5 6 2 7 5 9 10 11 1 12 13 14 15]
I have some rough code that I created to attempt this, but it will always minus the whole list including duplicated integers (the first pairs and any further pairs).
If someone can shed some light on how to deal with this problem i will be highly grateful!
Sorry forgot to add my code
a = [49, 51, 53, 56, 49, 54, 53, 48]
dupes = list()
number = 1
print (dupes)
while True:
#move integers from a to dupes (one by one)
for i in a[:]:
if i >= 2:
dupes.append(i)
a.remove(i)
if dupes in a:
a = [x - number for x in a]
print (dupes)
print(dupes)
if dupes in a:
a = [x - number for x in a]
number = number+1
break
Forgot to mention earlier, me and friend are currently working on this problem and the code i supplied is our rough outline of what is should look like and now the end result, I know that it does now work so i decided to ask for help for the issue
You need to iterate through your list and when you encounter a duplicate(can use list slicing) then decrement the next item!
List slicing - example,
>>> L=[2,4,6,8,10]
>>> L[1:5] # all elements from index 1 to 5
[4, 6, 8, 10]
>>> L[3:] # all elements from index 3 till the end of list
[8, 10]
>>> L[:2] # all elements from index beginning of list to second element
[2, 4]
>>> L[:-2] # all elements from index beginning of list to last second element
[2, 4, 6]
>>> L[::-1] # reverse the list
[10, 8, 6, 4, 2]
And enumerate
returns a tuple containing a count (from start which defaults to 0)
and the values obtained from iterating over sequence
Therefore,
mylist=[0, 1, 2, 3, 4, 5, 6, 2, 8, 5, 10, 11, 12, 1, 14, 15, 16, 17]
dup=0
for index,i in enumerate(mylist):
if i in mylist[:index]:
dup+=1
else:
mylist[index]-=dup
print mylist
Output:
[0, 1, 2, 3, 4, 5, 6, 2, 7, 5, 8, 9, 10, 1, 11, 12, 13, 14]

Categories