How to get the index in the 'in' statement in Python [duplicate] - python

This question already has answers here:
Finding the index of an item in a list
(43 answers)
Closed 9 years ago.
I wrote an if statement like:
if word in vocab:
print word
However, I also would like to know the matched word index in vocab.
Is there any way in Python can do this?
I just come up a solution that use vocab.index(word) to get the index, but this way go through the array twice (one in if statement, one call index()). I wonder there should be more efficiency method.
Thanks.

To avoid one loop, you can use a try-except clause (without using if ... in ...:)
try:
i = vocab.index(word)
except ValueError as e:
print e # Optional
i = -1

This is a case where I wish I could do assignment in an if statement, but I can't so this is the solution:
If vocab is a list:
try:
index = vocab.index(word)
except ValueError:
pass
else:
print index, word
if vocab is a str:
index = vocab.find(word)
if index >= 0:
print index, word

def getindex(iterable,target):
for idx,value in enumerate(iterable):
if value==target: return idx
return -1
Note that this WILL NOT work if you're trying to find a substring in a string (as I'm assuming, since you're doing if word in vocab. In that case you really should do:
try: idx = iterable.index(target)
except ValueError as e: # Not found
# Handle it
If you try to use the getindex function above, it will always return -1 for any value len(target) > 1 since it will break your iterable into its smallest iteration, which is by-letter for strings.

You should have a look at pythons enumerate
EDIT: Following with an example:
for i, j in enumerate(vocab):
if j == word:
print (i, j)

Related

Test the length of elements in a list

def lengthgood(x):
for i in x:
if len(i)<13
return i
else:
pass
def makeproperlist(x):
return x.split(',')
attendancelist=makeproperlist(input("attendee list:"))
final_list=list(filter(lengthgood,attendancelist))
for i in finallist:
print (i)
I want to write a programme of which I create a list in which only elements shorter than 14 can be a part of.
This is my code, but it keeps returning all the elements I put in, even if some of them are longer than 14?
I tried to print the len(i) and it says that it is 1 for every element in the list?
How do I solve this?
You shouldn't put a return within a loop; it'll only return the first element that matches your condition.
You also shouldn't be looping within your filter function, because you're actually looping over characters of strings, which are all length 1.
Therefore, the first character is always returning a truthy value, giving you back the initial input after filtering
You only need to check the input length, and filter functions should ideally return appropriate boolean conditions rather than truthy values (in your case return i is returning a non-empty string)
def lengthgood(x):
return len(x)<13
If you don't need to use filter(), you can write a list comprehension
final_list=[a if len(a) < 13 for a in attendancelist]
may be like that
flst = []
def croper(lst):
for i in lst:
flst.append(i) if len(i) < 13 else 0
lst = input("attendee list:").split(',')
croper(lst)
print(flst)
or shorter
def croper(lst):
return [i for i in lst if len(i) < 13]
lst = input("attendee list:").split(',')
print(croper(lst))
You want to create a list but you not define it anywhere in program simply done it with simply one function makeproperlist(x).
Try this code bro this will help you.
attendancelist=[]
while (True):
ch=input("Enter c for continue and e for exit : ")
if (ch=='c'):
def makeproperlist(x):
if x<=13:
attendancelist.append(x)
else:
print("Enter number which is <= to 13.")
makeproperlist(int(input("attendee list:")))
elif (ch=='e'):
break;
print("Your attendece list : ",attendancelist)

Checking if element is in tuple using if condition [duplicate]

This question already has answers here:
How to check if a tuple contains an element in Python?
(4 answers)
Closed 6 years ago.
I am trying to check if there is a certain digit inside my tuple using an if statement, but finding it hard. Whats wrong here?
def racaman(x):
y = x
w = (0,)
for i in range(y):
k = w[i]-x[i]
if k == i in w:
w = w + ((w[i]+x[i]),)
else:
w = w + ((w[i]-x[i]),)
You can replace 3 in the if condition to find a specific digit
def raceman(x):
#assuming x is tuple
if 3 in x:
print("found")
else:
print("not found")
raceman((1,2,3,4))
Please correct your question, paste code properly.
I am not sure what you are asking for but, I guess:
tupl = (1,2,3,4,5)
if 1 in tupl:
print('y')
else:
print('n')
I would recommend a list instead
def racaman(x):
w = [0]
for i in range(x):
k = w[i]-x[i]
if k in w: # fix this
w.append(w[i]+x[i])
else:
w.append(k) # already calculated
return w # did you want to return that?
This could simply be a matter of checking like so:
>>>n in t
Where n is the digit and t is the tuple, for example:
>>>2 in (1,2,3)
True
However it is not enough if you are looking for a digit and the elements are strings:
>>>2 in ('a1','a2','a3') #won't return desired output since digit '2' is part of a string
False
If so, you would need to resort to a more adaptive method, iterating over the elements of the tuple and testing each one with an appropriate regular expression (import re).

How to skip empty lists when iterating over lists within a list?

Take the following code as an example:
a = [['James Dean'],['Marlon Brando'],[],[],['Frank Sinatra']]
n = 0
for i in a:
print a[n][0]
n = n + 1
I seem to be getting an error with the index value:
IndexError: list index out of range
How do I skip over the empty lists within the list named a?
Simple:
for i in a:
if i:
print i[0]
This answer works because when you convert a list (like i) to a boolean in an if statement like I've done here, it evaluates whether the list is not empty, which is what you want.
You can check if the list is empty or not, empty lists have False value in boolean context -
for i in a:
if i:
print a[n][0]
n = n + 1
Also, instead of using n separately, you can use the enumerate function , which returns the current element as well as the index -
for n, i in enumerate(a):
if i:
print a[n][0] # though you could just do - print i[0]
You could either make a test, or catch the exception.
# Test
for i in a:
if a[n]:
print a[n][0]
n = n + 1
# Exception
for i in a:
try:
print a[n][0]
except IndexError:
pass
finally:
n = n + 1
You could even use the condensed print "\n".join(e[0] for e in a if e) but it's quite less readable.
Btw I'd suggest using using for i, element in enumerate(a) rather than incrementing manually n
Reading your code, I assume you try to get the first element of the inner list for every non empty entry in the list, and print that. I like this syntax:
a = [['James Dean'],['Marlon Brando'],[],[],['Frank Sinatra']]
# this filter is lazy, so even if your list is very big, it will only process it as needed (printed in this case)
non_empty_a = (x[0] for x in a if x)
for actor in non_empty_a : print (actor)
As mentioned by other answers, this works because an empty list is converted to False in an if-expression

finding the index of the first letter of a sub string in the main string

I am trying to find the index of the first letter of a sub string within the main string. The function acts exactly like the find method of python. I have created a find_chr function that gives me the index of a character in a string and I am using the find_chr to get the index of the substring.
def find_str(s,x):
i=0
if x in s:
return find_chr(s,x[i])
else:
return -1
My problem is that when I am using the string "IS GOING GOING" and substring as "ING", I am getting the index of the first "I", when I am expecting the index of the "I" of "ING". I will appreciate any input about changing the function to get the right index of the first letter of the substring.
In find_str you call find_chr(s,x[i]). This is calling find_chr with only x[i] (the ith part of the substring).
This should fix your problem
def find_chr(s,char):
i=0
step = len(char)
for j in range(len(s)+1):
ch = s[j:j+step]
if ch==char:
return (i)
break
i+=1
return -1
def find_str(s,x):
i=0
if x in s:
return find_chr(s,x)
else:
return -1
You aren't looping through the characters, you only check for i == 0 (i.e. the first character in s). You need to apply a "window" to the string, checking len(s) characters in a row:
def find_str(s, x):
if x in s: # is x present?
for i in range(len(s)): # work through string indices
if s[i:i+len(x)] == x: # does x start at current index?
return i
return -1
This should solve your problem:
def find_str(s, x):
i = 0
while i < len(s):
if s[i:i + len(x)] == x:
return i
else:
i += 1
print find_str('IS GOING GOING', 'ING')
Look up the use of the index function in strings. You will then happily replace all of that code with about 1 line.
Supplying the answer because of the following comments. Seriously though, if one is going to learn python, it is a good exercise to be aware of the methods available for an object.
>>> 'is going going'.index('ing')
5
or more generally
>>> fullstring.index(substring)
This should be marked as the correct answer because it is the simplest and most obviously correct. The complexity of the algorithms offered is way too high for this problem.
If the substring is not in the fullstring, a ValueError exception will be raised. So if you need a function, then it should return the index from a try or -1 (or None) from the except blocks.

In Python, how can I find the index of the first item in a list that is NOT some value?

Python's list type has an index(x) method. It takes a single parameter x, and returns the (integer) index of the first item in the list that has the value x.
Basically, I need to invert the index(x) method. I need to get the index of the first value in a list that does NOT have the value x. I would probably be able to even just use a function that returns the index of the first item with a value != None.
I can think of a 'for' loop implementation with an incrementing counter variable, but I feel like I'm missing something. Is there an existing method, or a one-line Python construction that can handle this?
In my program, the situation comes up when I'm handling lists returned from complex regex matches. All but one item in each list have a value of None. If I just needed the matched string, I could use a list comprehension like '[x for x in [my_list] if x is not None]', but I need the index in order to figure out which capture group in my regex actually caused the match.
Exiting at the first match is really easy: instead of computing a full list comprehension (then tossing away everything except the first item), use next over a genexp. Assuming for example that you want -1 when no item satisfies the condition of being != x,
return next((i for i, v in enumerate(L) if v != x), -1)
This is Python 2.6 syntax; if you're stuck with 2.5 or earlier, .next() is a method of the genexp (or other iterator) and doesn't accept a default value like the -1 above (so if you don't want to see a StopIteration exception you'll have to use a try/except). But then, there is a reason more releases were made after 2.5 -- continuous improvement of the language and its built-ins!-)
Using a list comprehension when you only need the first just feels slimy (to me). Use a for-loop and exit early.
>>> lst = [None, None, None, "foo", None]
>>> for i, item in enumerate(lst):
... if item: break
... else:
... print "not found"
...
>>> i
3
enumerate() returns an iterator that yields a tuple of the current index of the iterable as well as the item itself.
[i for i, x in enumerate(my_list) if x != value][0]
If you're not sure whether there's a non-matching item, use this instead:
match = [i for i, x in enumerate(my_list) if x != value]
if match:
i = match[0]
# i is your number.
You can make this even more "functional" with itertools, but you will soon reach the point where a simple for loop is better. Even the above solutions aren't as efficient as a for loop, since they construct a list of all non-matching indices before you pull the one of interest.
A silly itertools-based solution:)
import itertools as it, operator as op, functools as ft
def index_ne(item, sequence):
sequence= iter(sequence)
counter= it.count(-1) # start counting at -1
pairs= it.izip(sequence, counter) # pair them
get_1st= it.imap(op.itemgetter(0), pairs) # drop the used counter value
ne_scanner= it.ifilter(ft.partial(op.ne, item), get_1st) # get only not-equals
try:
ne_scanner.next() # this should be the first not equal
except StopIteration:
return None # or raise some exception, all items equal to item
else:
return counter.next() # should be the index of the not-equal item
if __name__ == "__main__":
import random
test_data= [0]*20
print "failure", index_ne(0, test_data)
index= random.randrange(len(test_data))
test_data[index]= 1
print "success:", index_ne(0, test_data), "should be", index
All this just to take advantage of the itertools.count counting :)

Categories