Indexing of Same Values in a List - python

Due to list.index(x) will only return the index in the list of the first item whose value is x. Is there any way to return every index of same values in the list.
For example, I have a list containing some same values like:
mylist = [(A,8), (A,3), (A,3), (A,3)]
I want to return:
index_of_A_3 = [1, 2, 3]

mylist = [(A,8), (A,3), (A,3), (A,3)]
def indices( mylist, value):
return [i for i,x in enumerate(mylist) if x==value]
print indices(mylist, (A,3))
# [1, 2, 3]

Replace (A,3) with what you want or use a lambda.
[i for i in range(len(mylist)) if mylist[i]==(A,3)]

It's kinda ugly but:
index_of_A_3 = [i for i in range(len(mylist)) if mylist[i] == (A,3)]

more quickly !!!!
index_of_A_3= np.where(mylist == (A,3))[0]

Related

How to find the postion of certain string in the list using abstract function

I am trying to find the position of certain string s in the list, but ONLY using the abstract function (ie. filter, map...).
find_all([], "") => []
find_all(["a","v","c","w","v"], "v") => [1,4]
I have tried the filter, but I don't know how to add the position in.
Use enumerate with list comprehension:
def find_all(l, k):
return [i for i,j in enumerate(l) if j == k]
Test:
find_all(["a","v","c","w","v"], "v")
find_all([], "")
Output:
[1, 4]
[]
Maybe something like this?
[item[0] for item in list(filter(lambda x : x[1] == 'v',enumerate(x)))]
Output:
[1, 4]

Finding indices of items from a list in another list even if they repeat

This answer works very well for finding indices of items from a list in another list, but the problem with it is, it only gives them once. However, I would like my list of indices to have the same length as the searched for list.
Here is an example:
thelist = ['A','B','C','D','E'] # the list whose indices I want
Mylist = ['B','C','B','E'] # my list of values that I am searching in the other list
ilist = [i for i, x in enumerate(thelist) if any(thing in x for thing in Mylist)]
With this solution, ilist = [1,2,4] but what I want is ilist = [1,2,1,4] so that len(ilist) = len(Mylist). It leaves out the index that has already been found, but if my items repeat in the list, it will not give me the duplicates.
thelist = ['A','B','C','D','E']
Mylist = ['B','C','B','E']
ilist = [thelist.index(x) for x in Mylist]
print(ilist) # [1, 2, 1, 4]
Basically, "for each element of Mylist, get its position in thelist."
This assumes that every element in Mylist exists in thelist. If the element occurs in thelist more than once, it takes the first location.
UPDATE
For substrings:
thelist = ['A','boB','C','D','E']
Mylist = ['B','C','B','E']
ilist = [next(i for i, y in enumerate(thelist) if x in y) for x in Mylist]
print(ilist) # [1, 2, 1, 4]
UPDATE 2
Here's a version that does substrings in the other direction using the example in the comments below:
thelist = ['A','B','C','D','E']
Mylist = ['Boo','Cup','Bee','Eerr','Cool','Aah']
ilist = [next(i for i, y in enumerate(thelist) if y in x) for x in Mylist]
print(ilist) # [1, 2, 1, 4, 2, 0]
Below code would work
ilist = [ theList.index(i) for i in MyList ]
Make a reverse lookup from strings to indices:
string_indices = {c: i for i, c in enumerate(thelist)}
ilist = [string_indices[c] for c in Mylist]
This avoids the quadratic behaviour of repeated .index() lookups.
If you data can be implicitly converted to ndarray, as your example implies, you could use numpy_indexed (disclaimer: I am its author), to perform this kind of operation in an efficient (fully vectorized and NlogN) manner.
import numpy_indexed as npi
ilist = npi.indices(thelist, Mylist)
npi.indices is essentially the array-generalization of list.index. Also, it has a kwarg to give you control over how to deal with missing values and such.

Python multiple loops

A = [[[1,2,3],[4]],[[1,4],[2,3]]]
Here I want to find lists in A which sum of all sublists in list not grater than 5.
Which the result should be [[1,4],[2,3]]
I tried a long time to solve this problem in python. But I still can't figure out the right solution, which I stuck at loop out multiple loops. My code as follows, but its obviously wrong, how to correct it?
A = [[[1,2,3],[4]],[[1,4],[2,3]]]
z = []
for l in A:
for list in l:
sum = 0
while sum < 5:
for i in list:
sum+=i
else:
break
else:
z.append(l)
print z
Asking for help~
Simplification of #KindStranger method in a one-liner:
>> [sub for x in A for sub in x if max(sum(sub) for sub in x) <= 5]
[[1, 4], [2, 3]]
A simple solution which you can think of would be like this -
A = [[[1,2,3],[4]],[[1,4],[2,3]]]
r = [] # this will be our result
for list in A: # Iterate through each item in A
f = True # This is a flag we set for a favorable sublist
for item in list: # Here we iterate through each list in the sublist
if sum(item) > 5: # If the sum is greater than 5 in any of them, set flag to false
f = False
if f: # If the flag is set, it means this is a favorable sublist
r.append(list)
print r
But I'm assuming the nesting level would be the same. http://ideone.com/hhr9uq
This should work for your problem:
>>> for alist in A:
... if max(sum(sublist) for sublist in alist) <= 5:
... print(alist)
...
[[1, 4], [2, 3]]
The one with all()
[t for item in A for t in item if all(sum(t)<=5 for t in item)]

How to iterate over a python list?

If I execute this code, the following error message occurs:
IndexError: list index out of range python
def reverse_invert(lst):
inverse_list = []
for i in lst:
if isinstance( i, int ):
inverse_list.append(lst[i])
#print(inverse_list)
print(i)
else:
break
return inverse_list
Why is it?
for i in lst:
will iterate the elements of lst.
If you want to iterate indexes, use
for i in range(len(lst)):
If you want both the element and the index, use enumerate:
for i, el in enumerate(lst):
You are iterating the elements of list but trying to use the element as index. You should change your code like this:
def reverse_invert(lst):
inverse_list = []
for i in lst:
if isinstance( i, int ):
inverse_list.append(i) # changed this one.
#print(inverse_list)
print(i)
else:
break
return inverse_list
List comprehension would work fine:
a = [1, 'a', 2, 3]
print [d for d in a[::-1] if isinstance(d, int)]
And if you want to reverse it just tiny change would do:
a = [1, 'a', 2, 3]
print [d for d in a[::-1] if isinstance(d, int)]
Or maybe I missed your point.
Generally it means that you are providing an index for which a list element does not exist.
E.g, if your list was
[1, 3, 5, 7], and you asked for the element at index 10, you would be well out of bounds and receive an error, as only elements 0 through 3 exist.

"local variable 's' referenced before assignment" error. How do I fix?

I am trying to make a list that takes in numbers and removes all the old numbers in the list and returns s the result, but it keeps on giving me the error "local variable 's' referenced before assignment" How do I fix it?
def purify(lst):
for item in lst:
if item%2 != 0:
lst.remove(item)
s.append(lst)
s = []
return s
It isn't clear why you want to return a list containing a single list. Why not just return the "purified" list?
def purify(lst):
return [item for item in lst if item % 2 == 0]
This uses a list comprehension. Demo:
>>> purify([1, 2, 3, 4, 5])
[2, 4]
For more flexibility, you could also make a version where you pass your own rule:
def purify(lst, rule):
return [item for item in lst if rule(item)]
Demo:
>>> purify([1, 2, 3, 4, 5], lambda i: i % 2)
[1, 3, 5]
You need to assign s to empty list first and then append.
def purify(lst):
for item in lst:
if item%2 != 0:
lst.remove(item)
s = []
s.append(lst)
return s
As #jonrsharpe suggested, don't remove the item while iterating over list. The good approach is using the list comprehension:
[i for i in lst if i%2!=0]
You should not remove items while iterating, because the list should not be changed when using iterators (this is what you do with "in").
def purify(lst):
s = []
for item in lst:
if item%2 == 0:
s += [item]
return s
btw: This can be done very fast with numpy.
import numpy as np
...
def purify(lst):
indices = np.where(np.mod(lst,2) == 0)
return np.array(lst)[indices]
Simplify your life with filter:
filter(lambda x: x % 2 == 0, range(5))

Categories