Finding indexes of a specific repeated number in array - python

I am trying to get the index of some repeated elements in an array. Here is the code:
cc = []
ang=[12,13,89.0,14,15,16,89.0,17]
class Index:
def __init__(self, **kwargs):
self.Angle = kwargs['Angle']
def ind(self):
for mm in range(0, len(self.Angle)):
if self.Angle[mm] == 89.0:
ee = self.Angle.index(self.Angle[mm])
cc.append(ee)
return cc
plus = Index(Angle=ang)
plus1 = plus.ind()
print (plus1)
I want to find the index of the repeated number = 89.0 in the list (ang). I am expecting to get [2,6] but I keep getting [2,2] which is wrong. Does anybody know how I can fix it? I know it may be possible to do it by changing the format of this code but I prefer to keep this format (using kwargs and class). Thanks!

This is because list.index(<element>) returns the index of the element. If the element appears more than once index() always returns index of the first occurrence.
However, in your code you don't need to call index since you are accessing the element via mm that is already the index. Why not just append mm. Like:
if self.Angle[mm] == 89.0:
cc.append(mm)
Moreover, same code can be elegantly written with list comprehension like:
indexes = [x for x in range(0, len(self.Angle)) if self.Angle[x] == 89.0]

Related

Replicate =LARGE and =SMALL function in Excel to Python

I would like to obtain the k-th largest/ k-th smallest value from numerical columns in a .xlsx file imported in Python. I have heard that a sorted array is required for the same.
So I tried isolating different columns into an array in Python using openpyxl like so
col_array = []
for i in range(1,1183):
col_array = factor2_db.cell(row=i,column=2).value
print(col_array)
And then used the function below to find the kth Largest value but that resulted in an error in Line 2
``
0 class Solution(object):
1 def findKthLargest(self,nums, k):
2 nums_sorted= sorted(nums) **TypeError: 'float' object is not iterable**
3 if k ==1:
4 return nums_sorted[-1]
5 temp = 1
6 return nums_sorted[len(nums_sorted)-k]
7 ob1 = Solution()
8 print(ob1.findKthLargest(col_array,5))
Soln
Strictly speaking, your variable col_array is not a multi-dimensional array - it's simply a single value presented as a list that gets overwritten 1182 times (i.e. range(1,1183)).
I tried the following and had favourable results:
col_array=[]
for i in range(10): col_array.append(i)
print(col_array)
you can customise the append using something (untested) like this: col_array.append( factor2_db.cell(row=i, column= 2).value)
def kth(k, large=False):
global col_array
col_array.sort(key=None, reverse=large)
print(f'col_array = {col_array}, col_array[{k}] = {col_array[k]}')
return col_array[k-1]
print(kth(4, True))
Noting the first element of a list is indexed 0, although you wouldn't ordinarily talk of returning the '0th' smallest / largest element, whence the adjustment -1 in return col_array[k-1]
Demonstration:
Additional notes:
To preserve the original ordering, replicate col_array at outset - one way to achieve this:
col_array_copy = []; col_array_copy += (x for x in col_array)
Then proceed as above after replacing 'col_array' with 'col_array_copy'.

Nested For Loop Copies the last line in set of indicies

for each in Dti:
i = 0
for each in Dti[0]:
xbi[t][i] = Dti[t][i]
print(t)
i = i + 1
t = t + 1
this is just a test that I'm doing to figure out why my complicated code isn't working. I'm trying to iterate through a list and then each value in the list to set a new list of lists equal to that value. I know I could just set them equal to each other, but it needs to be done this way for my more complicated program. Any tips? I'm getting Dti[-1] for each xbi[t]. I've tried with while too and got the same results
Try something like this:
for t, D in enumerate(Dti)
for i, d in enumerate(D):
xbi[t][i] = d
print(t)
You can use slicing in assignments to replace one list's elements with the elements of another list:
for t, row in enumerate(Dti):
xbi[t][:] = row

Custom Key for Sort Function Doesn't Work

Given an array A[] of integers, A has to be sorted according to frequency of elements. If frequencies of two elements are same, then smaller number comes first.
I've tried to solve the problem using the following code using the sort function but my custom key for the sort() does not seem to work. Can someone tell me what's going on here?
'''a is the input array and n is it's sizeQ'''
def sortByFreq(a,n):
def count(k):
return n-a.count(k)
a.sort(key=int)
a.sort(key=count)
a=list(map(str,a))
answer=' '.join(a)
print(answer)
For an input array [9,9,9,2,5], the code is supposed to print 9 9 9 2 5, (as the array already is), but it prints 2 5 9 9 9 instead. (The second time I call sort it does not seem to work)
The problem is that you just cannot use the original list inside a sort key, because sort uses an out of place location to compute the sort.
At some point, the original a is empty. Don't expect something like "all elements of a are in it" when calling the sort key.
In fact, if you print a in the count method, you'll get an empty list, everytime.
The workaround is to make a copy of the list and use it in the sort key (aside: no need to pass the size of the list, since len can compute that)
def sortByFreq(a):
def count(k):
return len(a_copy)-a_copy.count(k)
a_copy = a.copy() # create a copy of the list
a.sort(key=count)
a=list(map(str,a))
answer=' '.join(a)
print(answer)
an alternative is to pre-count elements with a counter (uses hashes, so faster). Note that you have to store the length of a too.
def sortByFreq(a):
def count(k):
return n-c[k]
c = collections.Counter(a)
n = len(a)
a.sort(key=count)
finally, a shorter way would use reverse=True to simplify sort key, which we can turn to a lambda:
def sortByFreq(a):
c = collections.Counter(a)
a.sort(key=lambda k:c[k],reverse=True)
def sort_by_frequency(sequence):
"""Sort sequence by frequency."""
return ''.join(sorted([char for char in sequence], key=sequence.count, reverse=True))
if __name__ == '__main__':
print(sort_by_frequency('92959'))

Removed element from list but range has changed?

I just learnt how to remove something from a list.
rando = keywords[random.randint(0, 14)]
h = 0
for h in range(len(keywords)):
if rando == keywords[h]:
position = h
realAns = definitions[position]
del keywords [h]
However, as I am using a while loop, a part of the code keeps repeating, and as I have changed the range by deleting an element, a traceback error occurs saying that it is out of range. How do i fix this?
Thanks :)
The code looks fine, may be you have not defined the list 'keywords' with 14 entries in the list.
You get the 'list out of range' error when you are trying to access a part of list which is not defined.
For example see following code
list_of_rollnumbers = [11,24,31,57,42,99,132]
print list_of_rollnumbers[7]
print list_of_rollnumbers[9] #both these would give list index out of range error
print list_of_rollnumbers[5] #this would print 99
Why are you even doing that loop? As I understand it, you pick the item at a random index, then look through the whole list to find the item so you can find its index. Just do:
position = random.randrange(len(keywords))
rando = keywords[position]
realAns = definitions[position]
Or, much simpler:
rando, realAns = random.choice(list(zip(keywords, definitions)))

Index error:list assignment index out of range

I want to:
Take two inputs as integers separated by a space (but in string form).
Club them using A + B.
Convert this A + B to integer using int().
Store this integer value in list C.
My code:
C = list()
for a in range(0, 4):
A, B = input().split()
C[a] = int(A + B)
but it shows:
IndexError: list assignment index out of range
I am unable understand this problem. How is a is going out of the range (it must be starting from 0 ending at 3)?
Why it is showing this error?
Why your error is occurring:
You can only reference an index of a list if it already exists. On the last line of every iteration you are referring to an index that is yet to be created, so for example on the first iteration you are trying to change the index 0, which does not exist as the list is empty at that time. The same occurs for every iteration.
The correct way to add an item to a list is this:
C.append(int(A + B))
Or you could solve a hella lot of lines with an ultra-pythonic list comprehension. This is built on the fact you added to the list in a loop, but this simplifies it as you do not need to assign things explicitly:
C = [sum(int(item) for item in input("Enter two space-separated numbers: ").split()) for i in range(4)]
The above would go in place of all of the code that you posted in your question.
The correct way would be to append the element to your list like this:
C.append(int(A+B))
And don't worry about the indices
Here's a far more pythonic way of writing your code:
c = []
for _ in range(4): # defaults to starting at 0
c.append(sum(int(i) for i in input("Enter two space-separated numbers").split()))
Or a nice little one-liner:
c = [sum(int(i) for i in input("Enter two space-separated numbers").split()) for _ in range(4)]

Categories